数据库事务系列5 分布式事务及其他
Posted 小耶哥
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了数据库事务系列5 分布式事务及其他相关的知识,希望对你有一定的参考价值。
本期作者由找钢网高级Java工程师才高7缸原创
10.分布式事务
10.1 mysql数据库分布式事务
Mysql存储引擎提供了对XA事务的支持,并通过XA事务来支持分布式事务的实现。
分布式事务指的是允许多个独立的事务资源参与到一个全局事务中。
事务资源通常是关系型数据库系统,也可以是其他类型的资源。全局事务要求,在其中的所有参与的事务要么全部提交,要么全部回滚。而且,使用分布式事务时,InnoDB存储引擎的事务隔离级别必须设置为serializable.
XA事务允许不同数据库之间的分布式事务,如一台数据库是mysql,了另外一台是oracle, 只要参与全局事务的每个节点都支持XA事务。
XA事务由一个或者多个资源管理器(Resource Managers), 一个事务管理器(Transaction manager), 以及一个应用程序组成。
资源管理器(RM):提供访问事务资源的方法,通常就是一个数据库。
事务管理器(TM):协调参与全局事务中的各个事务。需要和参与全局事务的所有资源管理器进行通信。在mysql中就是连接mysql服务器的客户端。
应用程序(APP):定义事务的边界,制定全局事务中的操作。
分布式事务使用两段式提交的方式:
第一阶段:所有参与全局事务的节点都开始准备(prapare), 告诉事务管理器他们准备好开始提交了。
第二阶段:事务管理器告诉资源管理器,开始提交或者回滚。
可见,与本地事务不同的是,分布式事务需要多一次的prepare操作,待收到所有节点的同意信息后,再进行提交或回滚操作。
通过命令show variables like 'innodb_support_xa'查看是否启用了对XA事务的支持。
分布式事务通常都是通过编程语言来实现的,java的JTA可以很好的支持Mysql的分布式事务。
Mysql数据库XA事务的sql语法:
XA {start | bgein} xid [join | resume]
XA end xid [suspend [for migrate]]
XA prepare xid
XA commit xud [one phase]
XA rollback xid
XA recover
10.2 内部XA事务
上一节讨论的分布式事务是外部事务,即资源管理器是mysql本身。但是在mysql中还存在另外一种分布式事务,其在存储引擎和插件之间,又或者在存储引擎与存储引擎之间,称为内部事务。
最常见的存在于binlog与Innodb存储引擎之间。在事务提交时,先写二进制日志,再写InnoDB存储引擎的重做日志。对这两个操作要求也是原子的,必须同时写入,否则会产生数据不一致。
苏州天平山初冬美景 宋老师摄于2019年冬
11.不好的事务习惯
11.1 在循环中提交
每一次提交都要写一次重做日志,所以要减少提交操作的次数。
可能有人存在这两种观点:
1.事务应该尽快的释放,不能有长时间的事务。
2.担心存在Oracle数据库中由于没有足够undo产生的Snapshot Too Old的经典问题。
但是,Mysql的InnoDB存储引擎没有上述两个问题,所以不应该在一个循环中反复提交事务。
11.2 使用自动提交
自动提交不是一个好习惯。可以通过set autocommit=0设置自动提交为手动提交。也可以使用start transaction, begin来显示开启事务。在显示开启事务后,默认情况下, mysql 会自动地执行set autocommit=0的命令,并在commit或rollback结束一个事务后,执行set autocommit=1.
11.3 使用自动回滚
InnoDB支持通过定义一个handler来进行自动事务的回滚操作,如在一个存储过程中发生了错误会自动回滚。
示例:
Create procedure sp_auto_rollback_demo()
Begin
Declare exit handler for SQLException rollback;
Start transaction;
Insert into b select 1;
Insert into b select 2;
Insert into b select 1;
Insert into b select 3;
Commit;
End;
假设存在唯一索引,当再次插入1时,会报错回滚。看起来没有问题,但是执行这个存储过程的结果到底是对是错?发生了什么错误?自动回滚就是存在这样的问题。
在程序中控制事务的好处是,用户可以得到发生错误的原因。
12.长事务
长事务,即执行时间较长的事务。
比如一条更新sql需要操作一亿条语句,用时超过1小时。由于事务的ACID的特性,这个操作被封装在一个事务中完成。这就存在一个问题,当执行中发生错误,数据库需要回滚所有已经发生的变化,这个过程可能时间更长,这个代价是不可接受的。
因此,我们尽量将长事务转化为小批量的事务来处理。当事务发生错误时,只需要回滚一小部分数据,然后接着上次已完成的事务继续进行。
往期回顾
InnoDB存储引擎系列
75道BAJT高级Java面试题专题
运维专家专题
经典回顾
微信支付专题
参考资料
1 | CSDN
责编 | 小耶哥
本期作者 | 才高7缸
平台建设及技术支持 | 小耶哥
以上是关于数据库事务系列5 分布式事务及其他的主要内容,如果未能解决你的问题,请参考以下文章