简述分布式事务有哪些?
二阶段提交:XA协议:需要有一个事务协调器。性能比较低。
第一阶段:pre commit:先尝试一下,把事务提前占用了,但是不提交。
第二阶段:commit或者是rollback,前一阶段占用成功,就提交;否则如果有失败的或者超时的就回退。
那么第二步的时候,如果有超时或者是报错,如何处理了?
这个时候就需要启动另外一个轮训的机制,去查询判断commit是否成功了。
如果事务协调者在发出第一阶段之后等一段时间之后没有收到事务参与者的返回,那么需要按照超时处理,协调者给参与者统一发出rollback操作。
但是如果事务参与者在第一阶段之后,过了一段时间没有收到事务协调者的请求,它是不能自行进行rollback操作的,因为这个时候有可能收到事务协调者的commit操作。
三阶段提交:
第一阶段:can commit,只是试一下,并不获取事务。
第二阶段:pre commit:把事务提前占用了,只不过是不提交。
第三阶段:commit或者是rollback,前一阶段占用成功,就提交;否则如果有失败的或者超时的就回退。
那么第三阶段的时候,如果事务协调者发现事务参与者有超时或者是报错,如何处理了?
这个时候依然启动另外一个轮训的机制,去查询判断commit是否成功了。
如果事务参与者在第二步之后长时间没有收到后续的请求,那么这时候和二阶段提交是不一样的,他可以继续commit。而不必阻塞在这里。
TCC:应用层级的两阶段提交。
Try:尝试。
Confirm:确定提交。这一阶段的操作需要保持幂等。
Cancel:取消回退。
如果参与方完成Try之后,迟迟没有收到请求方后续的请求操作,那么需要参与方自己调用cancel操作,以便释放资源。
CC的时候,如果出现超时或者错误,如何处理了?
saga协议
有一个saga协调器来进行事务的协调,不像二阶段一样,事务协调器需要等所有事务都返回。而是一个事务一个事务的顺序执行,如果后面的事务失败了,则需要将前面的事务进行冲正操作。
这样的问题是,有可能转账操作,刚开始的时候看起来是成功了,可能等一下却被回退了。
本地消息表:
可以将业务操作和本地消息事务表放到同一个事务里面操作。
然后本地消息事务表可以触发消息队列,然后触发后续的一系列操作。消息队列就可以保证至少有一次执行成功,这个时候后续的操作只能成功,而不能失败。
事务消息:
本地消息表的操作,还需要写一次数据库。有一些消息队列可以保证有且只有一次的高可用性,那么也可以使用消息队列中间件完成这个操作。
有些消息队列中间件原生支持了这个操作。
他的问题和上面本地消息表的问题是一样的。
编写分布式事务的时候需要注意空回滚、幂等和悬挂问题:
空回滚:就是没有try操作,但是来了cancel操作,这时候需要cancel能够返回成功。
幂等:就是相同请求重复发送,需要被调用方都返回相同的成功。
悬挂:就是后面的事务先执行,比如先执行cancel,后执行try,那么需要保证后面过来的try要是失败的。
------------------------
欢迎访问个人网站:
https://lessthinker.com
欢迎使用个人小程序: