一、背景在咱们应用Seata作为分布式事务时,有些时候咱们的分布式时候并不是每次都能够胜利的,而对于这些失败的分布式事务就须要进行告诉。这篇文章简略记录一下如何实现告诉。
二、性能实现此处模仿邮件告诉,然而不真正发送邮件,只是简略记录一个日志。三、注意事项1、 假如咱们的分布式事务回滚失败,在AT模式中是会锁定表记录数据的。前期须要获取这条记录的全局锁操作,都会失败。
举例:
假如存在如下数据表记录数据
账号金额zhangsan100zhangsan这条记录参加分布式事务。
在分布式事务中将 zhangsan 的金额批改成 90.另外一个共事,间接操作数据库,将 zhangsan 的记录批改成 80. (此时是能够批改胜利的,因为 Seata 是二阶段提交,在第一阶段完结后,会开释记录的本地锁,不开释记录的全局锁)接下来持续别的分布式事务操作,然而产生了异样,此时分布式事务会回滚失败,因为 zhangsan 的金额变成了80,和之前的对应不上。如果再次对 zhangsan 进行分布式事务操作或者须要获取全局锁的操作,那么都会失败。四、实现步骤1、编写一个类实现FailureHandler接口FailureHandler 的全类名为:io.seata.tm.api.FailureHandler,它有一个默认的实现DefaultFailureHandlerImpl, 此处咱们写一个类继承这个类。
package com.huan.seata.handler;import io.seata.tm.api.DefaultFailureHandlerImpl;import io.seata.tm.api.GlobalTransaction;import lombok.extern.slf4j.Slf4j;import org.springframework.stereotype.Component;/** * Seata 分布式事物失败的解决 * * @author huan.fu 2021/10/8 - 下午1:51 */@Component("failureHandler")@Slf4jpublic class EmailSeataFailureHandler extends DefaultFailureHandlerImpl { @Override public void onBeginFailure(GlobalTransaction tx, Throwable cause) { super.onBeginFailure(tx, cause); log.warn("邮件告诉:分布式事物出现异常:[onBeginFailure],xid:[{}]", tx.getXid()); } @Override public void onCommitFailure(GlobalTransaction tx, Throwable cause) { super.onCommitFailure(tx, cause); log.warn("邮件告诉:分布式事物出现异常:[onCommitFailure],xid:[{}]", tx.getXid()); } @Override public void onRollbackFailure(GlobalTransaction tx, Throwable originalException) { super.onRollbackFailure(tx, originalException); log.warn("邮件告诉:分布式事物出现异常:[onRollbackFailure],xid:[{}]", tx.getXid()); } @Override public void onRollbackRetrying(GlobalTransaction tx, Throwable originalException) { super.onRollbackRetrying(tx, originalException); log.warn("邮件告诉:分布式事物出现异常:[onRollbackRetrying],xid:[{}]", tx.getXid()); }}2、退出到Spring中的BeanName的值在测试的时候发现FailureHandler退出到Spring中的beanName必须是failureHandler,否则报错,是seata的主动配置中如下代码决定的。
...