不久之前团队有个新人问我一个很重要的web服务接口如何保证事务的问题。因为涉及到跨库事务,当时我只是回答目前我们的SOA框架都不支持跨库事务。然后就问到了数据库跨库事务是如何实现的,我只能凭印象含糊回答多数是基于数据库日志(后来知道就是所谓的预写日志Write-Ahead Logging),具体数据库内部如何控制数据一致性则真的说不清楚。后来一起查了一下事务的资料,原来DB的事务控制除了基于预写日志还要实现两阶段提交协议(2PC),参考MSDN摘抄两段加深印象。

一、2PC的两个阶段

1、准备阶段(Prepare Phase)

When the transaction manager receives a commit request, it sends a prepare command to all of the resource managers involved in the transaction. Each resource manager then does everything required to make the transaction durable, and all buffers holding log images for the transaction are flushed to disk. As each resource manager completes the prepare phase, it returns success or failure of the prepare to the transaction manager.

2、提交阶段(Commit Phase)

If the transaction manager receives successful prepares from all of the resource managers, it sends commit commands to each resource manager. The resource managers can then complete the commit. If all of the resource managers report a successful commit, the transaction manager then sends a success notification to the application. If any resource manager reported a failure to prepare, the transaction manager sends a rollback command to each resource manager and indicates the failure of the commit to the application.

二、2PC的原理示例

如何理解2PC实现分布式事务的呢?下面举例说明下。

假设有A、B、C三个数据库,A作为一个事务发起者,称为“主库”,B和C则称为”从库”。假设需要执行一个在A、B和C三个库的某个表中插入一行数据的事务。

准备阶段(Prepare Phase),A锁定表,并将事务写入自己的预写日志;A将事务发给从库B和C,B和C也各自锁定自己的表,并把事务写入预写日志,完成后返回告诉A准备阶段完成;
提交阶段(Commit Phase),A开始执行自己的事务,并通知B和C提交事务。如果在这个过程中没有任何错误,那么操作将在A、B和C库中完成;如果发生错误,比如从库C超时无响应,或者从库C磁盘空间不足…A将通知所有参与事务的B和C回滚该事务,并且回滚A自己的事务。

顺便重点再提一下预写日志,因为数据库的这种日志无比重要,普通的增删改查、数据还原、单库事务以及本文的分布式事务都离不开它,没有它绝大多数主流数据库的数据一致性根本无法实现。

到这里大家应该已经看到,相比单库事务,分布式事务控制更加复杂,而且开销极大。虽然一些高级开发框架如.net framework提供了较为强大丰富的类库如TransactionScope来简化开发分布式事务,但是建议能不用则不用,因为它被反映普遍存在性能问题无意识的死锁问题。这种分布式事务的场景如果频繁出现,重新拆分系统合理规划架构才是正道。

总结:在大型web应用中如何保持事务这个话题被问得非常多,个人已经是不止一次被问到所维护的站点是如何实现事务的。在分布式多集群环境下,业务逻辑错综复杂,保证数据库完全可靠存储当然并不容易。但是web应用程序的一个典型特点是读多写少,牺牲极少的数据一致性获得系统的高可扩展性可维护性以及高性能,那么一点点的数据不准确在业务上完全可以容忍,何况我们有日志,后续还有很多补偿措施,甚至直接人工介入处理也未尝不可。

参考:

http://msdn.microsoft.com/en-us/library/ms191440.aspx

http://technet.microsoft.com/zh-cn/library/ms186259(v=SQL.105).aspx

http://www.cnblogs.com/CareySon/archive/2012/02/13/2349751.html

http://www.cnblogs.com/CareySon/archive/2012/02/14/2351149.html

浅析SQL Server实现分布式事务的两阶段提交协议2PC的更多相关文章

  1. 分布式协议之两阶段提交协议(2PC)和改进三阶段提交协议(3PC)

    一. 事务的ACID 事务是保证数据库从一个一致性的状态永久地变成另外一个一致性状态的根本,当中,ACID是事务的基本特性. A是Atomicity,原子性.一个事务往往涉及到很多的子操作,原子性则保 ...

  2. sql server 锁与事务拨云见日(下)

    在锁与事务系列里已经写完了上篇中篇,这次写完下篇.这个系列俺自认为是有条不紊的进行,但感觉锁与事务还是有多很细节没有讲到,温故而知新可以为师矣,也算是一次自我提高总结吧,也谢谢大伙的支持.在上一篇的末 ...

  3. Microsoft SQL Server中的事务与并发详解

    本篇索引: 1.事务 2.锁定和阻塞 3.隔离级别 4.死锁 一.事务 1.1 事务的概念 事务是作为单个工作单元而执行的一系列操作,比如查询和修改数据等. 事务是数据库并发控制的基本单位,一条或者一 ...

  4. SQL Server 中的事务与事务隔离级别以及如何理解脏读, 未提交读,不可重复读和幻读产生的过程和原因

    原本打算写有关 SSIS Package 中的事务控制过程的,但是发现很多基本的概念还是需要有 SQL Server 事务和事务的隔离级别做基础铺垫.所以花了点时间,把 SQL Server 数据库中 ...

  5. 【转】SQL Server中的事务与锁

    SQL Server中的事务与锁   了解事务和锁 事务:保持逻辑数据一致性与可恢复性,必不可少的利器. 锁:多用户访问同一数据库资源时,对访问的先后次序权限管理的一种机制,没有他事务或许将会一塌糊涂 ...

  6. SQL Server中的事务日志管理(8/9):优化日志吞吐量

    当一切正常时,没有必要特别留意什么是事务日志,它是如何工作的.你只要确保每个数据库都有正确的备份.当出现问题时,事务日志的理解对于采取修正操作是重要的,尤其在需要紧急恢复数据库到指定点时.这系列文章会 ...

  7. MySQL binlog 组提交与 XA(分布式事务、两阶段提交)【转】

    概念: XA(分布式事务)规范主要定义了(全局)事务管理器(TM: Transaction Manager)和(局部)资源管理器(RM: Resource Manager)之间的接口.XA为了实现分布 ...

  8. SQL Server 2008 数据库同步的两种方式 (发布、订阅)

    参考转载: SQL Server 2008 数据库同步的两种方式 (发布.订阅) 使用Sqlserver事务发布实现数据同步

  9. sql server 锁与事务拨云见日(中)

    一.事务的概述 上一章节里,重点讲到了锁,以及锁与事务的关系.离上篇发布时间好几天了,每天利用一点空闲时间还真是要坚持.听<明朝那些事儿>中讲到"人与人最小的差距是聪明,人与人最 ...

随机推荐

  1. 安卓使用adb命令安装软件

    准备工作: 确信 \Android-sdk-windows\tools\下有 adb.exe     AdbWinApi.dll     AdbWinUsbApi.dll 三个文件,如果没有从\and ...

  2. Python 第五天 模块(2)

    模块,用一砣代码实现了某个功能的代码集合. 有两种存在的方式 1.写到一个文件夹里面 2.py文件 类似于函数式编程和面向过程编程,函数式编程则完成一个功能,其他代码用来调用即可,提供了代码的重用性和 ...

  3. 如果因特网中的所有链路都提供可靠的交付服务,TCP可靠传输服务是多余的吗?

    IP协议因为是无连接的, 所以其传输是不可靠的.虽然链路保证了数据包在端到端的传输中不发生差错,但是它不能保证IP数据包是按照正确的书需到达最终的目的地.IP数据包可以使用不同的路由通过网络,到达接收 ...

  4. Lnux 16.04 VM下安装与汉化

    参考linux-公社: http://www.linuxidc.com/Linux/2016-04/130520.htm  U盘安装linux16.04 http://www.linuxidc.com ...

  5. Linux三剑客之sed

    sed sed对文本的处理很强大,并且sed非常小,参数少,容易掌握,他的操作方式根awk有点像.sed按顺序逐行读取文件.然后,它执行为该行指定的所有操作,并在完成请求的修改之后的内容显示出来,也可 ...

  6. 关于libsvm工具箱在64位matlab下的安装说明

    LIBSVM工具箱的安装 基本方法: 1.在网上下载LIBSVM工具箱. http://www.csie.ntu.edu.tw/~cjlin/libsvm/ 2.将LIBSVM工具箱所在目录添加到MA ...

  7. MyBatis SQL动态装配

    MyBatis的方便在于可以配置动态SQL,通过过滤器进行动态装配.在刚开始使用中,遇到不少问题,其中update语句也需要动态装配,核心在于DAO层要与.xml文件中的语句和变量名要匹配.例如: D ...

  8. java中FileInputStream和FileOutputStream对图片操作的例子

    package a.ab; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.F ...

  9. Eclipse Debug

    [IT168 专稿]调试的方法虽然千千万万,但归根结底,就是找到引发错误的代码.Eclipse调试器的目标是让程序员能对本地或远程程序进行错误侦测与诊断.该调试器提供所有标准调试功能,包括进行单步执行 ...

  10. MQL4程序:一个号称成功率100%的EA程序 .mq4

    用​m​t​4​平​台​所​提​供​的​m​q​l​4​语​言​编​写​.​风​险​与​利​润​同​在​,​高​风​险​可​博​得​高​利​润​.​自​己​把​握​.​已​经​测​试​通​过​,​下​ ...