
1、@bruce 提问:
SOFAJRaft 可以实现在三个节点中选出一个 leader , 其他逻辑由自己实现吗?
A:可以,可以不用状态机,也不用加载和持久化快照, 只需要选个 leader。
各个节点如何知道自己是主节点还是从节点?
A:示例
SOFAJRaft:https://github.com/sofastack/sofa-jraft
2、@李明 提问:
全局事务执行过程中,有其他线程操作数据库,这时全局事务执行失败,在回滚的时校验数据发现数据被修改过,导致回滚失败,这种情况怎么避免?
A:其他线程也加上 global transactional 注解。分布式事务下,没有单个分支是独立的个体存在,需要拿到全局事务中,让其他事务知晓他的存在,从而避免在分布式调用链路中,恰好遇到同一个数据进行修改时,发生的脏写脏读 globallock 是在更新前去 tc 看下这个时候这个数据有没有被其他事务锁定,没有的话就说明这个数据没有被其他事务使用,是提交的数据,所以这叫读分布式事务下的已提交。
但是他并没有去注册分支,也就是他没有去占有这个全局锁,来达到分布式事务下的排他性。他在得到 tc 响应的时候,去执行 update 是有时间的,此时有个分布式事务下的分支 update 后,拿到了全局锁,然后他的链路二阶段是回滚 ,但是数据就被你这个认为没有全局锁的本地线程给改了,这就导致被干扰无法回滚。
所以 globallock 需要配合 sql 语句,在 update 前,先做 for update 这个数据,拿到这个数据的本地锁,拿到本地锁之后,再去 tc 判断有没有全局锁,如果 tc 没有锁,因为本地已经拿到本地锁了,具有本地事务的排他性,其他分支事务拿不到该数据的本地锁,是无法去注册分支去拿到全局锁,也就是禁止了其他分支事务的干扰,所以不会脏写。
目前 tcc 下一般就是 globallock+select for update 来防止被其他 at 事务改动后,进行了脏写。
3、@ 尚攀 提问:
Raft 是为了解决目前的什么问题?
A: 依赖外部存储。AT 有 before 镜像、after 镜像,after 镜像是在 undo_log 表里存储,那么 before 在哪里存储?未来的 raft 模式,集群支持动态扩缩容,事务信息存储在内存中(测试下来比 redis 快),现在的全局事务信息,分支事务信息,全局锁都是持久化到 db,或者 redis 去的。如果这个时候持久化用的 db 宕机了,Seata-Server 会不可用,而集成了 raft ,leader 宕机后自动选举新 leader,继续运转。所以,利用 raft 一致性算法,可以让多个 Seata 集群内存中的数据保持一致。
Seata:https://github.com/seata/seata
-
支持 yml 配置文件 -
支持 Oracle nclob 类型 -
支持客户端最少的活动负载均衡 -
支持客户端一致性哈希的负载均衡 -
支持 Spring Boot 使用自定义配置中心和注册中心 -
支持配置默认全局事务超时时间 -
多处 BUG 修复和功能优化

本文分享自微信公众号 - 金融级分布式架构(Antfin_SOFA)。
如有侵权,请联系 support@oschina.cn 删除。
本文参与“OSC源创计划”,欢迎正在阅读的你也加入,一起分享。