我的交易的完整性随着“;TransactionInDoutException”;例外
本文关键字:TransactionInDoutException 例外 交易 完整性 我的 | 更新日期: 2023-09-27 18:00:39
我有一个代码,它试图插入MSDTC事务中范围内的条目,如果插入失败,则会在特定阈值之前重试插入。
这是代码:
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;
}
}
遇到以下异常:
消息:交易有疑问。堆栈跟踪:在System.Transactions.TransactionStatePromotedInubt.PromotedTransactionResult(InternalTransactiontx)的System.Transactions.CommittableTransaction.Commit()位于的System.Transactions.TransactionScope.InteralDispose()位于的System.Transactions.TransactionScope.Dispose()Presensoft.Exchange2010Puch.Core.PushJob.SaveEmailAndSyncState()InnerException:System.Data.SqlClient.SqlException(0x80131904):超时已过期。在完成之前经过的超时时间操作或服务器没有响应。--->System.ComponentModel.Win32异常(0x80004005):等待操作在超时System.Data.SqlClient.SqlInternalConnection.OnError(SqlException异常,布尔breakConnection,操作`1 wrapCloseInAction)System.Data.SqlClient.TdsParser.ThrowExceptionAndWarning(TdsParserStateObjectstat eObj,布尔调用程序HasConnectionLock,布尔异步关闭)System.Data.SqlClient.TdsParserStateObject.ReadSniError(TdsParserStateObjectstateObj,UInt32错误)System.Data.SqlClient.TdsParserStateObject.ReadSniSyncOverAsync()
位于System.Data.SqlClient.TdsParserStateObject.TryReadNetworkPacket()
位于的System.Data.SqlClient.TdsParserStateObject.TryPrepareBuffer()System.Data.SqlClient.TdsParserStateObject.TryReadByte(字节和值)
位于System.Data.SqlClient.TdsParser.TryRun(RunBehavior RunBehavior,SqlCommand cmdHandler,SqlDataReader数据流,BulkCopySimpleResultSet bulkCopyHandler,TdsParserStateObjectstateObj,布尔&dataReady)System.Data.SqlClient.TdsParser.Run(RunBehavior RunBehavior,SqlCommand cmdHandler,SqlDataReader数据流,BulkCopySimpleResultSet bulkCopyHandler,TdsParserStateObjectstateObj)System.Data.SqlClient.TdsParser.TdsExecuteTransactionManagerRequest(Byte[]buffer,TransactionManagerRequestType请求,String transactionName,TransactionManagerIsolationLevel isoLevel,Int32超时,SqlInternalTransaction事务,TdsParserStateObject stateObj,布尔值isDelegateControlRequest)System.Data.SqlClient.SqlInternalConnectionTds.ExecuteTransactionYukon(TransactionRequesttransactionRequest,字符串transactionName,IsolationLevel iso,SqlInternalTransaction internalTransaction,布尔isDelegateControlRequest)System.Data.SqlClient.SqlDelegatedTransaction.SinglePhaseCommit(SinglePhaseEnlistment入伍)
此应用程序尝试重新插入条目后,接下来是
System.Data.SqlClient.SqlException(0x80131904):违反PRIMARYKEY约束"pk_email"。
在我看来,在没有事务的情况下,commit()成功(部分)提交已经在第一种情况下发生(MSDTC异常),这导致了后一种异常。
当出现"事务有疑问"异常时,我有没有办法查明是否发生了提交,如果有,我可以回滚提交。
根据MSDN:
当尝试对事务执行操作时引发此异常这是有疑问的。当无法确定交易。具体来说,事务,无论是提交还是中止,都不会因此而为人所知交易
当尝试提交交易,且该交易变为不确定。
这是一个可恢复的错误。
编辑:
用于恢复:你必须抓住TransactionInDoubtException
&使用apt检查编写补偿逻辑。
using (var scope = new TransactionScope(TransactionScopeOption.Required, option))
{
try
{
Context.SaveEmail(_emailInfoList);
context.SaveSyncState(syncState);
scope.Complete();
return true;
}
catch (TransactionInDoubtException ex)
{
//check whether any one record from the batch has been partially committed . If committed then no need to reprocess this batch.
// transaction scope should be disposed first .
scope.Dispose();
if (IsReprocessingNeeded(syncState))
throw;
return true;
}
}
/// <returns></returns>
private bool IsReprocessingNeeded(SyncStateDataModal syncState)
{
while (true)
{
try
{
var id = _emailInfoList[0].ID;
bool isEmailsCommitted = Context.GetJournalEmail().FirstOrDefault(a => a.ID == id) != null;
if (!isEmailsCommitted)
return true;
if (context.EmailSynch(syncState.Id) == null)
{
context.SaveSyncState(syncState);
}
return false;
}
catch (Exception ex)
{
Thread.Sleep(TimeSpan.FromMinutes(AppConfiguration.RetryConnectionIntervalInMin));
}
}
}
SOURCETransactionInDoutException的恢复路径是什么?