zoukankan      html  css  js  c++  java
  • 关于分布式事务的一个误解:使用了TransactionScope就一定会开启分布式事务吗?

    背景:

          事务是数据库管理系统的一个基本概念,事务具有四个基本特点,即ACID:原子性(Atomicity)、一致性(Consistency)、隔离性(Isolation)和持久性(Durability),通过事务机制可以保证数据库的一致性和完整性。

          不过数据库事务只能在数据库实例的同一个会话级别进行事务控制。而分布式事务可以协调一个数据库实例多个会话之间的操作,甚至是多个数据库实例之间的数据库操作,并保持事务特性。但是原则上我们不推荐使用分布式事务,因为分布式事务对资源消耗较多,执行效率较差。

          然而一直以来,我们对分布式事务的代码使用和效果都存在误解:使用了TransactionScope就一定会开启分布式事务吗?

    验证:

          我们做一个简单的Demo:两个连接字符串完全相同,ADO.NET会复用连接池中的连接,结果会如何?

        using (TransactionScope ts = new TransactionScope())
        {
            SqlConnection conn;
            conn = new SqlConnection("server=.;uid=tkk123;pwd=aaaaaa");
    
            conn.Open();
            SqlCommand cmd = conn.CreateCommand();
            cmd.CommandText = "select 1 as tkk";
            cmd.ExecuteNonQuery();
            conn.Close();
    
            conn = new SqlConnection("server=.;uid=tkk123;pwd=aaaaaa");
            conn.Open();
            cmd = conn.CreateCommand();
            cmd.CommandText = "select 2 as tkk";
            cmd.ExecuteNonQuery();
            conn.Close();
    
            ts.Complete();
        }
    
        Console.WriteLine("OK");
        Console.ReadKey();

    奇怪的事情发生了,并没有看到我们的以为的分布式事务!!!

    image

    我们更改其中的一个连接字符串,使得ADO.NET认为是两个数据源,这样才会真正意义上开启分布式事务。

        using (TransactionScope ts = new TransactionScope())
        {
            SqlConnection conn;
            conn = new SqlConnection("server=.;uid=tkk123;pwd=aaaaaa");
    
            conn.Open();
            SqlCommand cmd = conn.CreateCommand();
            cmd.CommandText = "select 1 as tkk";
            cmd.ExecuteNonQuery();
            conn.Close();
    
            conn = new SqlConnection("server=.;uid=tkk123;pwd=aaaaaa;"); --加了一个分号,不共享连接
            conn.Open();
            cmd = conn.CreateCommand();
            cmd.CommandText = "select 2 as tkk";
            cmd.ExecuteNonQuery();
            conn.Close();
    
            ts.Complete();
        }
    
        Console.WriteLine("OK");
        Console.ReadKey();

    让我们看一下分布式事务是如何协调每个数据库连接,当前的案例我们使用的是同一个数据库,所以虽然建立了两个数据库连接,但最终在数据库层面仍然是同一事务ID。

    如果我们打开的是两个不同数据库实例,将会看到什么样的结果呢? try it。。。

    image

  • 相关阅读:
    (转)学习笔记viewController(欢迎指错)
    配置Xcode版本控制SVN详细步骤内含解决Xcode/Mac OS10.8无法配置SVN的解决方法(转)
    iPhone 3G/3GS(有锁)基带与导航功能
    [转]Iphone 3G/3Gs Home键失灵的根本原因和解决方法
    NSDate的常用用法(转)
    短信操作(转)
    如何在Symbian SDK下使用GCCE4(转)
    nS60_sdk_v1_2的VC6问题(转)
    如何获取应用程序图标(转)
    如何实现圆角的UITextView iphone短信发送(非系统界面)
  • 原文地址:https://www.cnblogs.com/zhaoguan_wang/p/5848364.html
Copyright © 2011-2022 走看看