seata 手动回滚全局事务

1、seata 使用全局事务的时候,有时需要手动回滚事务,不需要抛异常则使用下面处理

import io.seata.core.context.RootContext;
import io.seata.core.exception.TransactionException;
import io.seata.core.model.GlobalStatus;
import io.seata.core.model.TransactionManager;
import io.seata.spring.annotation.GlobalTransactional;
import io.seata.tm.TransactionManagerHolder;
import io.seata.tm.api.GlobalTransaction;
import io.seata.tm.api.GlobalTransactionContext;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.Date;

@Slf4j
@Service
public class TestServiceImpl implements ITestService {

    @Autowired
    private ProductCollectionService productCollectionService;

    @Autowired
    private BaseUserServiceClient baseUserServiceClient;

    @GlobalTransactional
    @Override
    public void test() {

        String xid = RootContext.getXID();
        TransactionManager manager = TransactionManagerHolder.get();
        try {
            log.info("test 获取事务id {}", xid);

            ProductCollection collection = new ProductCollection();
            collection.setProductId(1L);
            collection.setUserId(1L);
            collection.setCreateTime(new Date());
            productCollectionService.save(collection);

            ResultBody resultBody = baseUserServiceClient.increaseUserScore(1L, 2, "2");

            log.info("test 开始回滚数据");
            GlobalStatus status = manager.rollback(xid);
        } catch (Exception e) {
            e.printStackTrace();
            try {
                manager.rollback(xid);
            } catch (TransactionException transactionException) {
                transactionException.printStackTrace();
            }
        }
    }

    @Override
    public void test1() {

        GlobalTransaction globalTransaction = GlobalTransactionContext.getCurrentOrCreate();

        try {
            globalTransaction.begin(300000, "my_test_tx_group");

            log.info("test1 获取事务 {}", globalTransaction.getXid());

            ProductCollection collection = new ProductCollection();
            collection.setProductId(1L);
            collection.setUserId(1L);
            collection.setCreateTime(new Date());
            productCollectionService.save(collection);

            ResultBody resultBody = baseUserServiceClient.increaseUserScore(1L, 2, "2");

            log.info("test1 开始回滚数据");
            globalTransaction.rollback();
        } catch (Exception e) {
            e.printStackTrace();
            try {
                log.info("test1 开始回滚数据");
                globalTransaction.rollback();
            } catch (TransactionException transactionException) {
                transactionException.printStackTrace();
            }
        }
    }

}

### Seata 分布式事务回滚机制 #### 1. 全局事务回滚流程 当全局事务中的某个分支事务执行失败时,Seata 的事务协调者 (TC) 将会通知所有的资源管理器 (RM),指示其回滚对应的分支事务。这一过程由 TM 发起,通过 TC 协调各个 RM 来实现最终的一致性[^2]。 #### 2. 回滚的具体操作 - **AT 模式下的自动补偿** 对于 AT 模式的分支事务,在业务 SQL 执行前后的数据快照会被记录下来。如果发生异常情况需要回滚,则可以通过对比前后镜像来自动生成反向更新语句来进行回滚操作。这种方式无需开发者额外编写代码即可完成自动化处理。 ```sql -- 假设这是原始的插入操作 INSERT INTO t_order (user_id, status) VALUES ('u_1', 'CREATED'); -- 如果后续步骤失败触发回滚,将会自动生成如下删除语句 DELETE FROM t_order WHERE user_id='u_1' AND status='CREATED'; ``` - **TCC 模式的手动控制** TCC 模式下,应用程序需显式定义 `try`、`confirm` 及 `cancel` 接口。其中 `cancel` 方法用于撤销已准备的操作;一旦检测到有未成功确认的情况存在,就会调用此方法来回退之前所做的准备工作。 ```java public class OrderService implements TccAction { @Override public boolean try() { // 准备阶段逻辑... return true; } @Override public void confirm() { // 确认阶段逻辑... } @Override public void cancel() { // 回滚阶段逻辑... } } ``` - **Saga 长活事务模型** Saga 流程是由一系列子事务构成的服务编排方式。每个子事务都关联着一对正向与逆向的方法。遇到错误时,系统会按照相反顺序依次调用这些逆向函数来逐步取消已完成的动作,从而达到整体上的原子性和一致性效果。 ```json [ {"name": "CreateOrder", "compensate": "CancelOrder"}, {"name": "ReserveStock", "compensate": "ReleaseStock"} ] ``` - **XA 模型的传统两阶段提交协议** XA 方案遵循标准的两阶段提交算法。第一阶段所有参与者都会被询问是否可以安全地继续前进至第二步;只有当所有人都同意之后才会进入真正的提交环节。如果有任何一个节点不同意或是在等待回复期间出现问题,则整个交易都将被打断并且回滚回去。 #### 3. 总结 综上所述,Seata 提供了多种灵活可靠的分布式事务回滚策略,能够满足不同应用场景的需求。无论是对于简单的数据库表变更还是复杂跨系统的交互场景都能有效保障数据一致性和可靠性。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值