I have a code that tries to insert entries scoped in a MSDTC transaction and if there is insert failure then insertion is retried up to a specific threshold.
Here is the code:
while(!SaveToDb){
.......
Thread.Sleep(TimeSpan.FromMinutes(AppConfiguration.RetryInsertionDuringFailureIntervalInMin));
}
private bool SaveToDb()
{
try
{
......
using (var scope = new TransactionScope(TransactionScopeOption.Required, option))
{
Context.SaveEmail(_emailInfoList);
Context.SaveSyncState(syncState);
scope.Complete();
return true;
}
}
catch (Exception ex)
{
........
return false;
}
}
And there is this exception encountered:
Message : The transaction is in doubt. Stack Trace : at System.Transactions.TransactionStatePromotedIndoubt.PromotedTransactionOutcome(InternalTransaction tx) at System.Transactions.CommittableTransaction.Commit() at System.Transactions.TransactionScope.InternalDispose() at System.Transactions.TransactionScope.Dispose() at Presensoft.Exchange2010Puch.Core.PushJob.SaveEmailAndSyncState() InnerException : System.Data.SqlClient.SqlException (0x80131904): Timeout expired. The timeout period elapsed prior to completion of the operation or the server is not responding. ---> System.ComponentModel.Win32Exception (0x80004005): The wait operation timed out at System.Data.SqlClient.SqlInternalConnection.OnError(SqlException exception, Boolean breakConnection, Action`1 wrapCloseInAction) at System.Data.SqlClient.TdsParser.ThrowExceptionAndWarning(TdsParserStateObject stat eObj, Boolean callerHasConnectionLock, Boolean asyncClose) at System.Data.SqlClient.TdsParserStateObject.ReadSniError(TdsParserStateObject stateObj, UInt32 error) at System.Data.SqlClient.TdsParserStateObject.ReadSniSyncOverAsync()
at System.Data.SqlClient.TdsParserStateObject.TryReadNetworkPacket()
at System.Data.SqlClient.TdsParserStateObject.TryPrepareBuffer() at System.Data.SqlClient.TdsParserStateObject.TryReadByte(Byte& value)
at System.Data.SqlClient.TdsParser.TryRun(RunBehavior runBehavior, SqlCommand cmdHandler, SqlDataReader dataStream, BulkCopySimpleResultSet bulkCopyHandler, TdsParserStateObject stateObj, Boolean& dataReady) at System.Data.SqlClient.TdsParser.Run(RunBehavior runBehavior, SqlCommand cmdHandler, SqlDataReader dataStream, BulkCopySimpleResultSet bulkCopyHandler, TdsParserStateObject stateObj) at System.Data.SqlClient.TdsParser.TdsExecuteTransactionManagerRequest(Byte[] buffer, TransactionManagerRequestType request, String transactionName, TransactionManagerIsolationLevel isoLevel, Int32 timeout, SqlInternalTransaction transaction, TdsParserStateObject stateObj, Boolean isDelegateControlRequest) at System.Data.SqlClient.SqlInternalConnectionTds.ExecuteTransactionYukon(TransactionRequest transactionRequest, String transactionName, IsolationLevel iso, SqlInternalTransaction internalTransaction, Boolean isDelegateControlRequest) at System.Data.SqlClient.SqlDelegatedTransaction.SinglePhaseCommit(SinglePhaseEnlistment enlistment)
After this application tries to reinsert the entries and what follows is
System.Data.SqlClient.SqlException (0x80131904): Violation of PRIMARY KEY constraint 'pk_email'.
It looks to me that without transaction.commit() firing up successfully (partial) commit already took place in the first case(MSDTC exception) which led to the latter exception.
Is there any way I can find out whether the commit has happened when there is "transaction is in doubt" exception and roll back the commit if there is any.