int mts_trx_commit (lock_trx_t * lt, int is_commit) { tp_dtrx_t *dtrx = lt->lt_2pc._2pc_info; tp_data_t *tpd = lt->lt_client->cli_tp_data; if (tpd && (CONNECTION_ENLISTED == tpd->cli_tp_enlisted)) { MTS_TRACE (("mts_trx_commit (connection level) %x\n", lt->lt_client)); return 0; } if (dtrx->dtrx_info) { HRESULT hr; MTS_TRACE (("mts_trx_commit (transaction level) %x\n", lt)); ITransaction *trx = ((mts_t *) dtrx->dtrx_info)->mts_trx; hr = is_commit ? trx->Commit (FALSE, 0, 0) : trx->Abort (0, 0, 0); trx->Release (); if (SUCCEEDED (hr)) return LTE_OK; return LTE_DEADLOCK; } return 0; }
int mts_trx_enlist_loc (client_connection_t * connection, ITransaction * itrn) { MTS_TRACE (("mts_trx_enlist_loc client (%x)\n", connection)); CTransactResourceAsync *ctra = 0; try { if (!itrn) { throw mts_error (0, "uninitialized ITransaction object"); } XACTUOW guid; long used; ctra = new CTransactResourceAsync; ITransactionEnlistmentAsync *enlistment; LOCK_OBJECT (local_rm); HRESULT hr = local_rm->rm->Enlist (itrn, ctra, &guid, &used, &enlistment); RELEASE_OBJECT (local_rm); MTS_THROW_ASSERT (hr, "Enlisting"); ctra->SetEnlistment (enlistment); ctra->SetConnection (connection); } catch (const mts_error & err) { delete ctra; err.dump (); return err.get_errcode (); } return 0; }
void * CTransactResourceAsync::operator new (size_t sz) { MTS_TRACE (("TRA::operator new...\n")); return dk_alloc (sz); };
int mts_trx_begin (query_instance_t * qi) { lock_trx_t *lt = qi->qi_trx; MTS_TRACE (("mts_trx_begin %x \n", lt)); ITransaction *transaction; try { Guard grd (local_rm_mutex); auto_interface < ITransactionOptions > options; HRESULT hr = local_rm->trx_dispenser->GetOptionsObject (&options.get ()); if (SUCCEEDED (hr)) { mts_set_trx_options (qi, &options.get ()); } hr = local_rm->trx_dispenser->BeginTransaction (0, ISOLATIONLEVEL_BROWSE, 0, options.get (), &transaction); MTS_THROW_ASSERT (hr, "BeginTransaction"); } catch (const mts_error & err) { err.dump (); return -1; } ((mts_t *) (lt->lt_2pc._2pc_info->dtrx_info))->mts_trx = transaction; return 0; }
void CTransactResourceAsync::operator delete (void *p) { MTS_TRACE (("TRA::operator delete\n")); dk_free (p, -1); }
ULONG CResMgrSink::Release () { InterlockedDecrement ((long *) &ref_count); MTS_TRACE (("IResourceManagerSink::ReleaseRef\n")); /* subject of change */ if (!ref_count) delete this; return ref_count; };
ULONG CTransactResourceAsync::Release () { InterlockedDecrement ((long *) &ref_count); MTS_TRACE (("TRA::ReleaseRef\n")); /* subject of change */ if (!ref_count) delete this; return ref_count; };
HRESULT CTransactResourceAsync::CommitRequest ( /* [in] */ DWORD grfRM, /* [in] */ XACTUOW __RPC_FAR * pNewUOW) { MTS_TRACE (("TRA::commit...\n")); mts_log_debug (("CommitRequest res=%p cli=%p", trx_enlistment_, client_connection_)); void * mts_message = mts_create_message (TP_COMMIT, trx_enlistment_, client_connection_); mq_add_message (tp_get_main_queue (), mts_message); return S_OK; };
HRESULT CTransactResourceAsync::AbortRequest ( /* [in] */ BOID __RPC_FAR * pboidReason, /* [in] */ BOOL fRetaining, /* [in] */ XACTUOW __RPC_FAR * pNewUOW) { MTS_TRACE (("TRA::abort...\n")); mts_log_debug (("AbortRequest res=%p cli=%p", trx_enlistment_, client_connection_)); void * mts_message = mts_create_message (TP_ABORT, trx_enlistment_, client_connection_); mq_add_message (tp_get_main_queue (), mts_message); return S_OK; };
HRESULT CTransactResourceAsync::PrepareRequest ( /* [in] */ BOOL fRetaining, /* [in] */ DWORD grfRM, /* [in] */ BOOL fWantMoniker, /* [in] */ BOOL fSinglePhase) { MTS_TRACE (("TRA::prepare...\n")); mts_log_debug (("PrepareRequest res=%p cli=%p", trx_enlistment_, client_connection_)); void * mts_message = mts_create_message (TP_PREPARE, trx_enlistment_, client_connection_); mq_add_message (tp_get_main_queue (), mts_message); return S_OK; };
HRESULT CResMgrSink::QueryInterface (const struct _GUID & guid, void **iFace) { MTS_TRACE (("IResourceManagerSink::QueryInterface\n")); if (guid == IID_IResourceManagerSink) { *iFace = this; return S_OK; }; if (guid == IID_IUnknown) { *iFace = static_cast < IUnknown * >(this); return S_OK; }; *iFace = 0; return E_NOINTERFACE; };
HRESULT CTransactResourceAsync::QueryInterface (const struct _GUID & guid, void **iFace) { MTS_TRACE (("TRA::QueryInterface\n")); if (guid == IID_ITransactionResourceAsync) { *iFace = this; return S_OK; }; if (guid == IID_IUnknown) { *iFace = static_cast < IUnknown * >(this); return S_OK; }; *iFace = 0; return E_NOINTERFACE; };
int mts_ms_sql_enlist (rds_connection_t * rcon, query_instance_t * qi) { lock_trx_t *lt = qi->qi_trx; if (rcon->rc_is_enlisted != SHOULD_BE_ENLISTED) { return 0; } mts_t *trx = (mts_t *) lt->lt_2pc._2pc_info->dtrx_info; MTS_TRACE (("mts_ms_sql_enlist %x\n", rcon)); ITransaction *itrx = 0; tp_data_t *tpd = qi->qi_client->cli_tp_data; if (tpd && CONNECTION_ENLISTED == tpd->cli_tp_enlisted) itrx = (ITransaction *) tpd->cli_tp_trx; else if ((!trx->mts_trx) && (mts_trx_begin (qi) == -1)) { return -1; } else itrx = trx->mts_trx; try { SQLRETURN sr = SQLSetConnectAttr (rcon->rc_hdbc, SQL_COPT_SS_ENLIST_IN_DTC, (SQLPOINTER) itrx, SQL_IS_INTEGER); if ((sr != SQL_SUCCESS) && (sr != SQL_SUCCESS_WITH_INFO)) { DoSQLError (rcon->rc_hdbc, 0); throw mts_error (sr, "SQLSetConnectOption"); } rcon->rc_is_enlisted = ENLISTED; } catch (const mts_error & err) { err.dump (); return -1; } return 0; }
mts_RM_t * init_RM () { MTS_TRACE (("init_RM\n")); mts_RM_t *rm = (mts_RM_t *) dk_alloc (sizeof (mts_RM_t)); memset (rm, 0, sizeof (mts_RM_t)); try { auto_interface < IResourceManagerFactory > rm_factory; HRESULT hr = DtcGetTransactionManager (0, 0, __uuidof (IResourceManagerFactory), 0, 0, 0, (void **) &rm_factory.get ()); MTS_THROW_ASSERT (hr, "Get RM Factory"); int guid = open ("guid.bin", O_RDONLY | O_BINARY); if (-1 == guid) { /* log_info("Generating RM GUID..."); */ guid = open ("guid.bin", O_CREAT | O_WRONLY | O_BINARY); UuidCreate (&VirtRMGUID); write (guid, &VirtRMGUID, sizeof (VirtRMGUID)); } else read (guid, &VirtRMGUID, sizeof (VirtRMGUID)); hr = rm_factory->Create (&VirtRMGUID, "Virtuoso Resource Manager", new CResMgrSink, &(rm->rm)); MTS_THROW_ASSERT (hr, "Create RM"); hr = DtcGetTransactionManager (0, 0, __uuidof (ITransactionDispenser), 0, 0, 0, (void **) &(rm->trx_dispenser)); MTS_THROW_ASSERT (hr, "Get Transaction Dispenser"); } catch (const mts_error & err) { err.dump (); vd_use_mts = 0; /* log_info ("MS DTC could not be found, call reconnect"); */ return 0; } return rm; }
int mts_trx_exclude (lock_trx_t * lt, rds_connection_t * rcon) { if (rcon->rc_is_enlisted != ENLISTED) return 1; try { MTS_TRACE (("mts_trx_exclude %x\n", rcon)); SQLRETURN sr = SQLSetConnectAttr (rcon->rc_hdbc, SQL_COPT_SS_ENLIST_IN_DTC, NULL, SQL_IS_INTEGER); MTS_THROW_SQLASSERT (sr, rcon->rc_hdbc, "SQLSetConnectOption"); rcon->rc_is_enlisted = 0; } catch (const mts_error & err) { err.dump (); } return 1; }
HRESULT CTransactResourceAsync::TMDown (void) { MTS_TRACE (("TRA::down...\n")); return S_OK; };
HRESULT CResMgrSink::TMDown () { MTS_TRACE (("IResourceManagerSink::shut down!\n")); return S_OK; };
ULONG CResMgrSink::AddRef () { InterlockedIncrement ((long *) &ref_count); MTS_TRACE (("IResourceManagerSink::AddRef\n")); return ref_count; };
ULONG CTransactResourceAsync::AddRef () { InterlockedIncrement ((long *) &ref_count); MTS_TRACE (("TRA::AddRef\n")); return ref_count; };