带有嵌套事务的TransactionScope

本文关键字:TransactionScope 嵌套事务 | 更新日期: 2023-09-27 18:12:21

using System;
using System.Transactions;
namespace ConsoleApplication3
{
    public class Program
    {
        public static void Main(string[] args)
        {
            var trans = new TransactionScope(TransactionScopeOption.RequiresNew);
            try
            {
                if (!ProcessMessage(true))
                {
                    MoveMessageToErrorQueue();
                }
                trans.Complete();
            }
            catch (Exception)
            {
                trans.Dispose();
            }
        }
        private static bool ProcessMessage(bool throwError)
        {
            //write to database
            var trans = new TransactionScope(TransactionScopeOption.Required);
            try
            {
                if (throwError)
                    throw new Exception();
                trans.Complete();
                return true;
            }
            catch (Exception)
            {
                trans.Dispose();
            }
            return false;
        }
        private static void MoveMessageToErrorQueue()
        {
            var trans = new TransactionScope(TransactionScopeOption.Required);
            trans.Complete();
        }
    }
}

我如何使MoveMessageToErrorQueue方法中的事务范围在主事务中登记,而不是在ProcessMessage方法中的一个?

当它试图在MoveMessageToErrorQueue中创建一个新的事务时,我得到一个异常,说明事务已经中止。

如果我使用CommittableTransaction

,我得到相同的结果
using System;
using System.Transactions;
namespace ConsoleApplication3
{
    public class Program
    {
        public static void Main(string[] args)
        {
            using (var trans = new CommittableTransaction())
            {
                try
                {
                    if (!ProcessMessage(trans, true))
                    {
                        MoveMessageToErrorQueue(trans);
                    }
                    trans.Commit();
                }
                catch (Exception)
                {
                    trans.Rollback();
                }                
            }
        }
        private static bool ProcessMessage(Transaction trans, bool throwError)
        {
            //write to database
            var transScope = new TransactionScope(trans);
            try
            {
                if (throwError)
                    throw new Exception();
                transScope.Complete();
                return true;
            }
            catch (Exception)
            {
                transScope.Dispose();
            }
            return false;
        }
        private static void MoveMessageToErrorQueue(Transaction trans)
        {
            var transScope = new TransactionScope(trans);
            transScope.Complete();
        }
    }
}

基本上,如果ProcessMessage方法中的事务失败,我希望能够在最后一个方法中仍然使用相同的根事务。

谢谢你的帮助。

更新2

"在DTC事务(以及使用该模式的事务)中,失败是致命的且立即的。一、注定的旗帜立起来了,它立起来了。"

这说明了一切。

带有嵌套事务的TransactionScope

使用嵌套的transactionscope仍然只有一个事务。嵌套作用域不会创建新事务。事务不能嵌套。系统。Transactions不支持此操作。也不支持保存点。

当你回滚一个嵌套作用域时,你会毁掉整个事务。

我不知道如何得到你想要的行为。与系统。事务你必须避免任何破坏当前事务的事情。也许你可以使用SQL Server的保存点来撤消失败的ProcessMessage的影响。或者,您可以为ProcessMessage和MoveMessageToErrorQueue使用不同的DB连接。

"在DTC事务(以及使用该模式的事务)中,失败是致命的且立即的。一、注定的旗帜立起来了,它立起来了。"

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