目录:
1.什么是事务?
2.换个角度看事务
3.Java中的事务
4.啥又是分布式事务?
5.分布式事务的几种实现思路
6.总结
写在前面
在分布式、微服务大行其道的今天,相信大家对这些名词都不会陌生。而说到使用分布式,或者拆分微服务的好处,你肯定能想到一大堆。
比如每个人只需要维护自己单独的服务,没有了以前的各种代码冲突。自己想测试、想发布、想升级,只需要care自己写的代码就OK了,很方便很贴心!
然而事物都有两面性,但是它也同时也会带来的一些问题,今天的文章谈的就是分布式系统架构带来的其中一个棘手的问题:分布式事务
1、什么是事务?
首先抛出来一个问题:什么是事务?
有人会说事务就是一系列操作,要么同时成功,要么同时失败;然后会从事务的ACID特性(原子性、一致性、隔离性、持久性)展开叙述。
确实如此,事务就是为了保证一系列操作可以正常执行,它必须同时满足ACID特性。
但是今天我们换个角度思考下,我们不仅要知道what(比如什么是事务),更要知道事务的why(比如为什么会有事务这个概念?事务是为了解决什么问题)。
有时候,换个角度说不定有不一样的收获。
2、换个角度看事务
就像经典的文学作品均来自于生活,却又高于生活,事务的概念同样来自于生活,引入“事务”肯定是为了解决某种问题,不然,谁又愿意干这么无聊的事情呢?
最简单最经典的例子:银行转账,我们要从A账户转块到B账户。
正常情况下如果从A转出到B账户之后,A账户余额减(这个操作我们用action1代表),B账户余额加(这个操作我们用action2代表)
首先我们要明确一点,action1和action2是两个操作。既然是两个操作那么就一定会存在执行的先后顺序。那么就可能会出现action1执行完刚准备去执行action2的时候出问题了(比如数据库负载过大暂时拒绝访问)。
类比到我们生活中,那就是我给朋友转了块钱,然后我卡里的余额少了,但是我朋友确没有收到钱。
为解决这种“money去哪儿了”的问题,引入了“事务”的概念。也就是说,既然我转账的时候你保证不了%能成功,比如银行系统只能保证99.99%的高可用,那么在那0.01%的时间里如果出现了上述问题,银行系统直接回滚action1操作?(即把块钱再加回余额中去)
对于银行系统来说,可能在0.01%的时间里我保证不了action1和action2同时成功,那么在出问题的时候,我保证它俩同时失败。(事务的原子性)
通过这个例子,就已经回答了刚开始提出的2个问题(为什么会有事务?事务是为了解决什么问题?)
总结一下:事务就是通过它的ACID特性,保证一系列的操作在任何情况下都可以安全正确的执行。
3、Java中的事务
搞清楚了事务之后,我们来看点眼熟的,java中的事务是怎么玩的?
Java中我们平时用的最多的就是在service层的增删改方法上添加
Transactional注解,让spring去帮我们管理事务。它底层会给我们的service组件生成一个对应的proxy动态代理,这样所有对service组件的方法都由它对应的proxy来接管
当proxy在调用对应业务方法比如add()时,proxy就会基于AOP的思想在调用真正的业务方法前执行setAutoCommit(false)打开事务。
然后在业务方法执行完后执行