我的交易的完整性随着“;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异常),这导致了后一种异常。

当出现"事务有疑问"异常时,我有没有办法查明是否发生了提交,如果有,我可以回滚提交。

我的交易的完整性随着“;TransactionInDoutException”;例外

根据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的恢复路径是什么?

相关文章:
  • 没有找到相关文章