阿里分布式事务解决方案seata使用问题汇总

  • 1 Seata报错get global lock fail(lock_table 中数据没有插入导致取锁取不到)


1 Seata报错get global lock fail(lock_table 中数据没有插入导致取锁取不到)

seatunnel报错Configuration item validate failed seata常见错误_分布式事务

java.sql.BatchUpdateException: Data truncation: Data too long for column 'table_name'
 at row 1
 seata lock_table表中的字段长度太小。导致Seata报错get global lock fail

2 seata分布式事务如何保证事务的隔离性

怎么使用Seata框架,来保证事务的隔离性?
订单服务和库存服务。
开启全局事务后,库存服务已提交本地事务,50库存修改为49,全局事务未提交。
另外线程只有本地事务,修改库存从49到48。
然而订单服务报错,全局事务需要回滚,这时会全局事务会回滚失败,出现脏数据。
有什么好的方案去处理这种情况吗?或者避免这种情况的发生

这就是@GlobalLock的作用。另外一个本地事务去读数据时,会阻塞住,直到全局事务完成,他才能读到全局事务结束后的正确的数据。这样就避免了脏读和脏写。
A: 因seata一阶段本地事务已提交,为防止其他事务脏读脏写需要加强隔离。脏读 select语句加for update,
代理方法增加@GlobalLock+@transactional或@GlobalTransaction
脏写 必须使用@GlobalTransaction
注:如果你查询的业务的接口没有GlobalTransactional 包裹,也就是这个方法上压根没有分布式事务的需求,
这时你可以在方法上标注@GlobalLock+@transactional 注解,并且在查询语句上加 for update。
如果你查询的接口在事务链路上外层有GlobalTransactional注解,那么你查询的语句只要加for update就行
。设计这个注解的原因是在没有这个注解之前,需要查询分布式事务读已提交的数据,但业务本身不需要分布式事务。
若使用GlobalTransactional注解就会增加一些没用的额外的rpc开销比如begin 返回xid,提交事务等。
GlobalLock简化了rpc过程,使其做到更高的性能。
你也可以选择开启后置镜像校验,回滚时,会去校验数据有没有被更改。
https://github.com/seata/seata/issues/2488