因为工作场景的原因,没能有机会用到事物。因为我的工作内容是预先处理将近二十亿的数据,然后更多的是提供查询。并且这些数据存在elasticsearch中。所以事物基本上不会用到。
最近在休假,看看我所没有触及到的技术。提升一下自己!
先来理解一下本地事物和分布式事物的区别 什么是本地事物呢如果只是表象的介绍,对于java语言,使用springboot的话,就是一个 @Transaction 注解,开启事物。
所谓的本地事物有一个前提,因为他是基于一个数据库连接来完成的。所以应该是同一个数据库。并且这个连接应该来自于同一个项目。
与之相反的分布式事物 分布式场景一:不同是数据库简单易用,高性能,比较靠谱的解决方案:阿里开源的seata
seata官网链接地址:http://seata.io/zh-cn/docs/overview/what-is-seata.html
seata中主推的 AT(auto transaction) 模式工作原理:
- seata通过拦截sql,对sql进行解析,得到更新的语句是对哪个数据库、哪个表、哪条数据进行更新的,并且查询该数据的id。
- 然后将查询的数据作为befer Image,也就是当做回滚的点数据,一旦事物需要回滚,那么这得回滚点就会被拿出来,反向补偿这条数据,也就是把修改的数据回复原状。
- 有了回滚点以后,就相当于是完成了第一阶段(准备阶段),然后等着其他业务库都完成准备阶段。然后就可以去执行真正的减库存等操作了。在完快照以后,需要对这条数据加一个行锁,否则如果一旦事物回滚,别的下单操作,就会脏读这条数据。所以加了行锁,就无法读这条数据了。行锁的释放时机就是这次全局事物都完成了,没有产生异常不需要进行回滚。则释放行锁,其他下单行为可以继续操作这条数据了。在执行完数据库的修改操作以后,再打一个befor image,记录一下修改后的现状。 befer Image 和 befor image 将会合并成一条undo log。这条undo log将用来恢复原状。
- AT模式,是两阶段提交,上述的第三步就是第一阶段。那么第二阶段要做的就是事物提交。要么就执行成功了,要么就执行失败了。执行成功,则把过程中的before image还原点,删除了就可以了,以及过程中为了防止脏读加的行锁释放掉。而执行失败,则把第一个阶段打的还原点,进行补偿。把数据恢复成原状。
优点:简单易用 - 无侵入(不需要在业务中多写任何代码),高性能,并且支持高可用。
缺点:
- seata主推的是 AT模式,也就是两阶段提交。但是AT模式不可比避免的是过程中需要加行锁,这是不可避免的会降低吞吐量。
- 实际上,还是需要额外的维护一个数据库,用来维护事物协调者。存放undo log。
- 虽然试用起来很容易,只需要在我们的代码层面上加上一个 @GlobelTransaction ,但是还是额外的做了很多的工作。我们应该搭建起来一个seata的运行环境。