关于TransactionScope事务的TransactionScopeOption的实例

namespace TransactionScopeOptionTest
{
    class Program
    {
        static void Main(string[] args)
        {
            using (TransactionScope ts = new TransactionScope())
            {
                Console.WriteLine(Transaction.Current.TransactionInformation.LocalIdentifier);
                int randomNum = new Random().Next(10000);
                Console.WriteLine($"randomNum={randomNum}");
                string strCon = ConfigurationManager.ConnectionStrings["TCITLog"].ToString();
                LogEntity entity = new LogEntity()
                {
                    EventID = randomNum,
                    Priority = randomNum,
                    Severity = "title1",
                    Title = "title1",
                    Timestamp = DateTime.Now,
                    MachineName = "my pc",
                    AppDomainName = "domain",
                    ProcessID = "12",
                    ProcessName = "process",
                    ThreadName = "thread",
                    Message = "this is a msg"
                };
                int PKID = 0;//新增数据
                // 新增数据操作,需要引入TCG.Framework.SqlData命名空间
                int result = entity.InsertToSql(strCon);
                if (result > 0)
                {
                    PKID = entity.LogID; // 新增完数据后,自增长字段(LogID)会被自动赋值
                    Console.WriteLine($"Add data Success, PKID1={PKID}, EventID1 = {entity.EventID}");
                }

                using (TransactionScope ts2 = new TransactionScope(TransactionScopeOption.Required))
                {
                    Console.WriteLine(Transaction.Current.TransactionInformation.LocalIdentifier);
                    LogEntity entity2 = new LogEntity()
                    {
                        EventID = randomNum,
                        Priority = randomNum,
                        Severity = "title2",
                        Title = "title2",
                        Timestamp = DateTime.Now,
                        MachineName = "my pc",
                        AppDomainName = "domain",
                        ProcessID = "12",
                        ProcessName = "process",
                        ThreadName = "thread",
                        Message = "this is a msg"
                    };
                    // 新增数据操作,需要引入TCG.Framework.SqlData命名空间
                    int result2 = entity2.InsertToSql(strCon);
                    if (result2 > 0)
                    {
                        var PKID2 = entity2.LogID; // 新增完数据后,自增长字段(LogID)会被自动赋值
                        Console.WriteLine($"Add data Success, PKID2={PKID2}, EventID2 = {entity2.EventID}");
                    }
                    //ts2.Complete();
                }

                ts.Complete();
            }
            Console.WriteLine("事务完成");
            Console.ReadLine();
        }
    }
}

通过实践证明:

1. 如果嵌套事务使用 TransactionScopeOption.Required,则注释掉 ts2.Complete();,且开启 ts.Complete();运行时报错,提示事务已中止。如果开启 ts2.Complete();,且注释掉 ts.Complete();运行时不报错,但2个操作都不成功。

只有当2个事务都运行到事务正常提交的代码后,2个操作才会都成功。因为他们是同一个事务ID,所以可以当做一个事务看待,2个事务都需要提交事务才算整体成功。

2. 如果嵌套事务使用 TransactionScopeOption.RequiresNew,则嵌套事务和外部事务是2个不同编号的事务,相当于嵌套事务和外部事务没关系了,不管外部事务是否提交,都不影响嵌套事务的成功结果。反过来,不管嵌套事务是否提交,也都不影响外层事务的操作结果。相当于这2个事务是并列关系,彼此没有任何影响。

3. 如果嵌套事务使用 TransactionScopeOption.Suppress,则嵌套事务包含的代码相当于没有事务包裹的代码,就和没有事务存在一样,也不受外层事务的影响,嵌套事务自己不管是否提交也不影响最后结果,嵌套事务内部的代码就等于完全脱离了事务的限制,内外事务都不会影响到他,不管内外事务是否有提交,都相当于有提交事务的操作。

猜你喜欢

转载自www.cnblogs.com/itjeff/p/12119464.html