背景:

事务是数据库管理系统的一个基本概念,事务具有四个基本特点,即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();

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

我们更改其中的一个连接字符串,使得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。。。

关于分布式事务的一个误解:使用了TransactionScope就一定会开启分布式事务吗?的更多相关文章

  1. 事务隔离级别与传播机制,spring+mybatis+atomikos实现分布式事务管理

    1.事务的定义:事务是指多个操作单元组成的合集,多个单元操作是整体不可分割的,要么都操作不成功,要么都成功.其必须遵循四个原则(ACID). 原子性(Atomicity):即事务是不可分割的最小工作单 ...

  2. 对 COM+ 组件进行了方法调用,但该组件有一个已被中止的或正在被中止的事务。 (异常来自 HRESULT:0x8004E003)

    错误: 对 COM+ 组件进行了方法调用,但该组件有一个已被中止的或正在被中止的事务. (异常来自 HRESULT:0x8004E003)   解决办法: 程序连接的数据库换到本地.   具体原因没搞 ...

  3. 对Spring事务的一些误解

    提起spring事务,就会让人联想起四大基本特征,五个隔离级别,七大传播特性.相信大多数人都知道这些东西,但是知道是一回事情,能用好真的是另一回事了.在使用Spring事务的时候,我曾遇到过几个比较严 ...

  4. 使用spring声明式事务,spring使用AOP来支持声明式事务,会根据事务属性,自动在方法调用之前决定是否开启一个事务,并在方法执行之后决定事务提交或回滚事务。

    使用spring声明式事务,spring使用AOP来支持声明式事务,会根据事务属性,自动在方法调用之前决定是否开启一个事务,并在方法执行之后决定事务提交或回滚事务.

  5. Java中的多表&事务&DCL&一个多表操作例子

    准备sql: 创建部门表 CREATE TABLE dept( id INT PRIMARY KEY AUTO_INCREMENT, NAME VARCHAR(20) ); INSERT INTO d ...

  6. 分布式跟踪的一个流行标准是OpenTracing API,该标准的一个流行实现是Jaeger项目。

    https://github.com/jaegertracing/jaeger https://mp.weixin.qq.com/s/-Tn2AgyHoq8pwMun8JHcGQ Jaeger的深入分 ...

  7. 发现Spring事务的一个实锤bug,官方还拒不承认?你来评评理...

    你好呀,我是歪歪. 事情是这样的,上周我正在全神贯注的摸鱼,然后有个小伙伴给我发来微信消息,提出了自己关于事务的一个疑问,并配上两段代码: 先说结论:我认为这是 Spring 事务的一个 bug.但是 ...

  8. 开启分布式事物DTC

    1.web服务器开启分布式事物配置后,数据库服务器的host文件要设置  “IP  web服务器主机名” 的映射,否则会 出现 “与基础事务管理器的通信失败” #跨网段使用TransactionSco ...

  9. 第三百五十七节,Python分布式爬虫打造搜索引擎Scrapy精讲—利用开源的scrapy-redis编写分布式爬虫代码

    第三百五十七节,Python分布式爬虫打造搜索引擎Scrapy精讲—利用开源的scrapy-redis编写分布式爬虫代码 scrapy-redis是一个可以scrapy结合redis搭建分布式爬虫的开 ...

随机推荐

  1. Kali安装小问题解决及一些设置

    昨天按照完Kali linux之后,更改了镜像源, 然后运行了 apt-get update && apt-get dist-upgrade 发现要 等大约两个小时才能跟新完毕.. 于 ...

  2. C++ Daily 《6》---- 类静态对象与函数静态对象

    C++ 的一个哲学基础是,你不应该为你使用的东西付出代价. class 拥有一个 static 成员,即使从未被用到,它也会被构造和析构: 而 函数拥有一个 static 成员, 如果这个函数从未被调 ...

  3. docker基本操作

    centos 7 安装docker 目前,CentOS 仅发行版本中的内核支持 Docker. Docker 运行在 CentOS 7 上,要求系统为64位.系统内核版本为 3.10 以上. Dock ...

  4. 解决 WPF AllowsTransparency = true 和 Webbrowser 等控件显示冲突

    代码: public class FormsWebBrowser { Window _owner; FrameworkElement _placementTarget; Form _form; AxA ...

  5. BZOJ3669 (动态树)

    Problem 魔法森林 (NOI2014) 题目大意 给n个点,m条边的无向图,每条边有两个权值a,b. 求一条从1-->n的路径,使得这条路径上max(a)+max(b)最小.输出最小值即可 ...

  6. Lua查找表元素过程(元表、__index方法是如何工作的)

    近日开始研究Lua,在元表的使用上照猫画虎地搞了两下,实现了“面向对象”,但究其本质却略有不解,后咨询牛哥得解,特此记录. Lua的表本质其实是个类似HashMap的东西,其元素是很多的Key-Val ...

  7. android view:手势

    一直认为android手势识别很是神奇,我们不分析复杂的手势,仅仅是针对上一次的基本事件的手势处理,分析GestureDetector的源码,来看一下到底手势事件是如何定义的. GestureDete ...

  8. 用python+selenium登录cnblog后新增文章后再次删除该文章

    目的:登录cnblog后新增文章后再次删除该文章并验证 代码如下: #coding: utf-8 from selenium import webdriver from time import sle ...

  9. php读取json时无数据(为空)的解决方法

    在使用PHP调用一些json接口文件时 如果使用 file_get_contents 获取页面json数据后 再使用json_decode()解析后 数据无法正常输出 这是的返回值为null 这是由于 ...

  10. Reconstruct Itinerary

    Given a list of airline tickets represented by pairs of departure and arrival airports [from, to], r ...