|
|
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
// Microsoft WMIOLE DB Provider
// (C) Copyright 1999 Microsoft Corporation. All Rights Reserved.
//
// ITransLocal.cpp
// ITransactionLocal interface Implementation
//
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////
#include "headers.h"
/////////////////////////////////////////////////////////////////////////////////////////////////
//
// Commits a transaction
//
// Returns one of the following values:
// S_OK Method Succeeded
// E_FAIL a provider specific error occured
// XACT_E_ABORTED Transaction was aborted before Commit
// DB_E_UNEXPECTED An unexpected error occured
// XACT_E_COMMIT_FAILED Transaction commit failed due to unknow reason. Txn Aborted
// XACT_E_CONNECTION_DOWN Connection to datasource down
// XACT_E_NOTRANSACTION transaction had already been implicitly or explicityly commited/aborted
// XACT_E_NOTSUPPORTED Invalid combination of commit flags was specified
//
/////////////////////////////////////////////////////////////////////////////////////////////////
STDMETHODIMP CImpITransactionLocal::Commit (BOOL fRetaining, DWORD grfTC, DWORD grfRM) { HRESULT hr = S_OK; CSetStructuredExceptionHandler seh;
TRY_BLOCK;
// Seriliaze the object
CAutoBlock cab(m_pCDBSession->GetCriticalSection());
// Clear Error information
g_pCError->ClearErrorInfo();
//==============================================
// check if transaction is already started
//==============================================
if(!m_pCDBSession->IsTransactionActive()) { hr = XACT_E_NOTRANSACTION; } else { //===============================================================================================
// call this functin to Commit transactions
//===============================================================================================
if(SUCCEEDED(hr = m_pCDBSession->m_pCDataSource->m_pWbemWrap->CompleteTransaction(FALSE,0))) // put the commit function here
{ m_pCDBSession->SetTransactionActive(FALSE); } }
if(SUCCEEDED(hr) && fRetaining) { m_pCDBSession->SetAllOpenRowsetToZoombieState(); } hr = hr == S_OK ? hr :g_pCError->PostHResult(hr,&IID_ITransactionLocal);
CATCH_BLOCK_HRESULT(hr,L"ITransactionLocal::Commit"); return hr; }
/////////////////////////////////////////////////////////////////////////////////////////////////
//
// Aborts a transaction
//
// Returns one of the following values:
// S_OK Method Succeeded
// E_FAIL a provider specific error occured
// DB_E_UNEXPECTED An unexpected error occured
// XACT_E_CONNECTION_DOWN Connection to datasource down
// XACT_E_NOTRANSACTION transaction had already been implicitly or explicityly commited/aborted
// XACT_E_NOTSUPPORTED fAsync was TRUE on input and async abort operation not supported
//
/////////////////////////////////////////////////////////////////////////////////////////////////
STDMETHODIMP CImpITransactionLocal::Abort (BOID *pboidReason, BOOL fRetaining, BOOL fAsync) { HRESULT hr = S_OK; CSetStructuredExceptionHandler seh;
TRY_BLOCK;
// Seriliaze the object
CAutoBlock cab(m_pCDBSession->GetCriticalSection());
// Clear Error information
g_pCError->ClearErrorInfo();
if(fAsync) { hr = XACT_E_NOTSUPPORTED; } else if(fRetaining) { hr = XACT_E_CANTRETAIN; } //==============================================
// check if transaction is already started
//==============================================
else if(!m_pCDBSession->IsTransactionActive()) { hr = XACT_E_NOTRANSACTION; } else { //===============================================================================================
// call this functin to Abort transactions
//===============================================================================================
if(SUCCEEDED(hr = m_pCDBSession->m_pCDataSource->m_pWbemWrap->CompleteTransaction(TRUE,0))) // put the commit function here
{ m_pCDBSession->SetTransactionActive(FALSE); } }
if(SUCCEEDED(hr)) { m_pCDBSession->SetAllOpenRowsetToZoombieState(); } hr = hr == S_OK ? hr :g_pCError->PostHResult(hr,&IID_ITransactionLocal);
CATCH_BLOCK_HRESULT(hr,L"ITransactionLocal::Abort"); return hr; }
/////////////////////////////////////////////////////////////////////////////////////////////////
//
// Get information regarding transaction
//
// Returns one of the following values:
// S_OK Method Succeeded
// E_FAIL a provider specific error occured
// DB_E_UNEXPECTED An unexpected error occured
// DB_E_INVALIDARG pInfo was a null pointer
// XACT_E_NOTRANSACTION Unable to retrieve info because txn was already completed
//
/////////////////////////////////////////////////////////////////////////////////////////////////
STDMETHODIMP CImpITransactionLocal::GetTransactionInfo (XACTTRANSINFO *pinfo) { HRESULT hr = S_OK; CSetStructuredExceptionHandler seh;
TRY_BLOCK;
// Seriliaze the object
CAutoBlock cab(m_pCDBSession->GetCriticalSection());
// Clear Error information
g_pCError->ClearErrorInfo();
if(pinfo == NULL) { hr = E_INVALIDARG; } else if(!m_pCDBSession->IsTransactionActive()) { hr = XACT_E_NOTRANSACTION; } else { // XACTUOW uow;
// GetCurrentUOW(uow);
pinfo->uow = m_pCDBSession->GetCurrentUOW(); pinfo->isoLevel = m_pCDBSession->GetIsolationLevel(); pinfo->isoFlags = 0; pinfo->grfTCSupported = XACTTC_SYNC; pinfo->grfRMSupported = 0; pinfo->grfTCSupportedRetaining = 0; pinfo->grfRMSupportedRetaining = 0; } hr = hr == S_OK ? hr :g_pCError->PostHResult(hr,&IID_ITransactionLocal);
CATCH_BLOCK_HRESULT(hr,L"ITransactionLocal::GetTransactionInfo"); return hr; }
/////////////////////////////////////////////////////////////////////////////////////////////////
//
// Get the options object for the transaction
// Returns an object which can be used to specify configuration options for subsequent
// call to ITransactionLocal::StartTransaction
//
// Returns one of the following values:
// S_OK Method Succeeded
// E_FAIL a provider specific error occured
// DB_E_UNEXPECTED An unexpected error occured
// DB_E_INVALIDARG ppObtions was a null pointer
// E_OUTOFMEMORY unable to allocate memory
//
/////////////////////////////////////////////////////////////////////////////////////////////////
STDMETHODIMP CImpITransactionLocal::GetOptionsObject(ITransactionOptions ** ppOptions) { HRESULT hr = E_INVALIDARG; CSetStructuredExceptionHandler seh;
TRY_BLOCK;
// Seriliaze the object
CAutoBlock cab(m_pCDBSession->GetCriticalSection());
// Clear Error information
g_pCError->ClearErrorInfo();
if(ppOptions) { *ppOptions = NULL; CTranOptions *pNewOptions = NULL; hr = E_OUTOFMEMORY; try { pNewOptions = new CTranOptions; } catch(...) { SAFE_DELETE_PTR(pNewOptions); throw; }
if(pNewOptions) { hr = S_OK; if(SUCCEEDED(hr = pNewOptions->FInit())) { hr = pNewOptions->QueryInterface(IID_ITransactionOptions , (void **)ppOptions); } else { SAFE_DELETE_PTR(pNewOptions); } } } hr = hr == S_OK ? hr :g_pCError->PostHResult(hr,&IID_ITransactionLocal);
CATCH_BLOCK_HRESULT(hr,L"ITransactionLocal::GetOptionsObject"); return hr; }
/////////////////////////////////////////////////////////////////////////////////////////////////
//
// Begins a new transaction
//
// Returns one of the following values:
// S_OK Method Succeeded
// E_FAIL a provider specific error occured
// DB_E_OBJECTOPEN a rowset object was open and provider does not support starting a
// new transaction with an existing open rowset/row object open
// DB_E_UNEXPECTED An unexpected error occured
// XACT_E_CONNECTIONDENIED session could not create a new transaction at the present time
// XACT_E_CONNECTION_DOWN Session is having communication difficulties
// XACT_E_NOISORETAIN Requested semantics of retention of isolation across retaining
// commit/abort boundaries cannot be supported or isoFlags was
// not equal to zero
// XACT_E_XTIONEXISTS Session can handle only one extant transaction ata time and
// there is presently such a transaction.
//
/////////////////////////////////////////////////////////////////////////////////////////////////
STDMETHODIMP CImpITransactionLocal::StartTransaction( ISOLEVEL isoLevel, ULONG isoFlags, ITransactionOptions *pOtherOptions, ULONG *pulTransactionLevel) { HRESULT hr = S_OK; CSetStructuredExceptionHandler seh; LONG lFlags = 0;
TRY_BLOCK;
// Seriliaze the object
CAutoBlock cab(m_pCDBSession->GetCriticalSection());
// Clear Error information
g_pCError->ClearErrorInfo();
//==============================================
// check if transaction is already started
//==============================================
if(m_pCDBSession->IsTransactionActive()) { hr = XACT_E_XTIONEXISTS; } else { XACTOPT xOpt; GUID guidTrans; // NTBug:111816
// 06/07/00
hr = CoCreateGuid(&guidTrans); xOpt.ulTimeout = 0; memset(xOpt.szDescription,0,MAX_TRAN_DESC * sizeof(unsigned char));
if(SUCCEEDED(hr) && pOtherOptions) { hr = pOtherOptions->GetOptions(&xOpt); } if(SUCCEEDED(hr)) { if(SUCCEEDED(hr = GetFlagsForIsolation(isoLevel,lFlags))) { //===============================================================================================
// call this functin to start a transaction
//===============================================================================================
if(SUCCEEDED(hr = m_pCDBSession->GenerateNewUOW(guidTrans)) && SUCCEEDED(hr = m_pCDBSession->m_pCDataSource->m_pWbemWrap->BeginTransaction(xOpt.ulTimeout,lFlags,&guidTrans))) // put the commit function here
{ m_pCDBSession->SetTransactionActive(TRUE); m_pCDBSession->SetIsolationLevel(isoLevel); if(pulTransactionLevel) { *pulTransactionLevel = 1; } } } } } hr = hr == S_OK ? hr :g_pCError->PostHResult(hr,&IID_ITransactionLocal);
CATCH_BLOCK_HRESULT(hr,L"ITransactionLocal::StartTransaction"); return hr; }
HRESULT CImpITransactionLocal::GetFlagsForIsolation(ISOLEVEL isoLevel,LONG &lFlag) { HRESULT hr = S_OK; lFlag = 0; switch(isoLevel) { case ISOLATIONLEVEL_READCOMMITTED: lFlag = 0; break; /*
case ISOLATIONLEVEL_CURSORSTABILITY: case ISOLATIONLEVEL_REPEATABLEREAD: //lFlags = Read
break;
case ISOLATIONLEVEL_SERIALIZABLE: case ISOLATIONLEVEL_ISOLATED: // lFlags = write
break; */
default: hr = XACT_E_ISOLATIONLEVEL;
}
return hr; }
|