聊聊分布式事务,再说说解决方案
分布式事务CAP理解论证-解决方案
分布式系统的2PC、3PC详细分析
github tcc示例
分布式事务、重复消费、顺序消费html
CAP与BASE相关:个人博客mysql
而对于分布式中的问题的解决方案,CAP原则出现,描述以下:git
一致性(Consistency):github
像A节点写入一条信息以后,同一时刻,在其余节点均可以读到这条信息spring
可用性(Availability):sql
多布一些节点A,B,C…,任什么时候刻,用户访问,都应该以可预期的结果返回,而不是浏览器报错,404,500,页面丢失…等用户体验很差的状况发生数据库
分区容忍性(PartitionTolerance):浏览器
当各系统模块间通讯出现问题时,设计一个策略,使系统仍可对外提供知足一致性或可用性springboot
刚接触cap时,有些不理解分区容忍性,咱们本身倒推一下:服务器
因此分区容忍性就是:当发生分区问题时,咱们使用策略,在一致性和可用性两者间选择
注意: 没法通讯包括网络问题,或者节点机器宕机
误区: CAP理论中说三者不可兼得,但实际状况是,在分布式场景中分区必定存在,即必须有分区容忍性对应的策略,以后才能在一致性和可用性间两者之间选择.因此对主流架构来讲不是三选二,而是二选一。
不少人可能对分区容忍性不太理解,知乎有一个回答对这个解释的比较清楚CAP理论中的P究竟是个什么意思?,这里引用一下:
http://www.jasongj.com/big_data/two_phase_commit/
http://www.javashuo.com/article/p-uoynwnjq-gm.html
XA规范中,事务管理器主要经过如下的接口对资源管理器进行管理
XA规范:http://www.javashuo.com/article/p-htncjnzz-cp.html
a. XA事务和本地事务以及锁表操做是互斥的
开启了xa事务就没法使用本地事务和锁表操做:
mysql> xa start 't1xa'; Query OK, 0 rows affected (0.04 sec) mysql> begin; ERROR 1399 (XAE07): XAER_RMFAIL: The command cannot be executed when global transaction is in the ACTIVE state mysql> lock table t1 read; ERROR 1399 (XAE07): XAER_RMFAIL: The command cannot be executed when global transaction is in the ACTIVE state
开启了本地事务就没法使用xa事务:
mysql> begin; Query OK, 0 rows affected (0.00 sec) mysql> xa start 'rrrr'; ERROR 1400 (XAE09): XAER_OUTSIDE: Some work is done outside global transaction
b. xa start 以后必须xa end, 不然不能执行xa commit 和xa rollback
因此若是在执行xa事务过程当中有语句出错了,你也须要先xa end一下,而后才能xarollback。
注意事项:
a. mysql只是提供了xa事务的接口,分布式事务中的mysql实例之间是互相独立的不感知的。 因此用户必须
本身实现分布式事务的调度器
b. xa事务有一些使用上的bug, 参考http://www.mysqlops.com/2012/02/24/mysql-xa-optimize.html
主要是:
“MySQL数据库的主备数据库的同步,经过Binlog的复制完成。而Binlog是MySQL数据库内部XA事务的协调者,而且MySQL数据库为binlog作了优化——binlog不写prepare日志,只写commit日志。
全部的参与节点prepare完成,在进行xa commit前crash。crash recover若是选择commit此事务。因为binlog在prepare阶段未写,所以主库中看来,此分布式事务最终提交了,可是此事务的操做并未 写到binlog中,所以也就未能成功复制到备库,从而致使主备库数据不一致的状况出现。
而crash recover若是选rollback, 那么就会出现全局不一致(该分布式事务对应的节点,部分已经提交,没法回滚,而部分节点回滚。最终致使同一分布式事务,在各参与节点,最终状态不一致)”
参考的那篇blog中给出的办法是修改mysql代码,这个没法在DBScale中使用。 因此可选的替代方案是不使用
主从复制进行备份,而是直接使用xa事务实现同步写来做为备份。
两个角色:
两个阶段:
牺牲了一部分可用性来换取的一致性。解决方案有:springboot+Atomikos or Bitronix
优势: 原理简单,实现方便
缺点:
JTA(Java Transaction API)定义了对XA事务的支持。像不少其余的Java规范同样,JTA仅仅定义了接口,具体的实现则是由供应商(如J2EE厂商)负责提供,目前JTA的实现主要有如下几种:
MySQL中的XA实现分为:外部XA和内部XA。前者是指咱们一般意义上的分布式事务实现;后者是指单台MySQL服务器中,Server层做为TM(事务协调者),而服务器中的多个数据库实例做为RM,而进行的一种分布式事务,也就是MySQL跨库事务;也就是一个事务涉及到同一条MySQL服务器中的两个innodb数据库(由于其它引擎不支持XA)。
是二阶段的改进版,将二阶段的提交事务请求过程一分为二,造成了:
在阶段二中,参与者可能会响应no,或者协调者等待超时时间后还没法收到全部参与者的反馈,则中断事务:协调者向全部参与者发送abort请求。参与者不管是收到协调者的abort请求,或者等待协调者请求过程当中超时,都会中断事务。
在阶段三中,若是有任一参与者发送了no,或者等待超时后协调者还没收到全部参与者的反馈,则中断事务。须要注意的事,进入阶段三,可能会有下面两种故障:
不管哪一种状况,都会致使参与者没法及时收到来自协调者的doCommit或者abort请求,这种状况,参与者在等待超时后继续进行事务提交。
优势:
缺点:
todo