【问题标题】:Does partial commit happen when TransactionInDoubtException is encountered? [duplicate]遇到 TransactionInDoubtException 时是否会发生部分提交? [复制]
【发布时间】:2014-04-30 07:35:59
【问题描述】:

遇到TransactionInDoubtException 时是否会发生部分提交?如果是这样如何回滚提交/正确处理TransactionInDoubtException

var option = new TransactionOptions();
option.IsolationLevel = IsolationLevel.ReadCommitted
using (var scope = new TransactionScope(TransactionScopeOption.Required, option))
{
    try
    {
         Context.SaveEmail(_emailInfoList);
         context.SaveSyncState(syncState);
         scope.Complete();
         return true;
    }
    catch (TransactionInDoubtException ex)
    {
         // Looks like commit has already taken place 
         // How to roll back the changes ??
         // sth like scope.Rollback()
    }
}

【问题讨论】:

    标签: c# sql-server sql-server-2008 msdtc


    【解决方案1】:

    根据MSDN

    尝试对事务执行操作时会引发此异常 这是有疑问的。当交易的状态存在疑问时 交易无法确定。具体来说,的最终结果 事务,无论是提交还是中止,都不会因此而为人所知 交易。

    当尝试提交 交易,交易变成InDoubt。

    这是一个可恢复的错误。

    编辑:

    为了恢复: 你必须抓住TransactionInDoubtException& 用恰当的检查编写补偿逻辑。

    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));
                    }
                }
            }
    

    来源 What is the recovery path for TransactionInDoubtException ?

    【讨论】:

    • 恢复路径是什么?
    • 这如何提供问题的答案。它更适合发表评论而不是回答。
    猜你喜欢
    • 2021-06-15
    • 1970-01-01
    • 1970-01-01
    • 2014-06-02
    • 1970-01-01
    • 1970-01-01
    • 2020-01-13
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多