Seata 分布式事务

2PC分布式事务参考

https://blog.csdn.net/hfmbook/article/details/120173076

Seata 分布式事务

和2PC的区别,2PC在最后提交阶段可能失败,失败了 其他服务事务执行成功,可能存在数据不一致情况。Seata在这里做了一个反向补偿。当某个服务提交失败,其他都提交成功情况,seata会提交一个执行新的sql将数据 回滚到原来的样子。

AT 模式

一阶段 prepare 行为:在本地事务中,一并提交业务数据更新和相应回滚日志记录。
二阶段 commit 行为:马上成功结束,自动 异步批量清理回滚日志。
二阶段 rollback 行为:通过回滚日志,自动 生成补偿操作,完成数据回滚。

TCC模式

一阶段 prepare 行为:调用 自定义 的 prepare 逻辑。
二阶段 commit 行为:调用 自定义 的 commit 逻辑。
二阶段 rollback 行为:调用 自定义 的 rollback 逻辑。

SEAGA

Saga模式是SEATA提供的长事务解决方案,在Saga模式中,业务流程中每个参与者都提交本地事务,当出现某一个参与者失败则补偿前面已经成功的参与者,一阶段正向服务和二阶段补偿服务都由业务开发实现。

seata server

# registry.conf
registry {
  type = "file" 
}

config {
  type = "file"  
  file {
    name = "file.conf"
  }
}

#file.conf
## transaction log store, only used in seata-server
store {
  mode = "file"
  publicKey = ""
  file {
    ## store location dir
    dir = "sessionStore"
    # branch session size , if exceeded first try compress lockkey, still exceeded throws exceptions
    maxBranchSessionSize = 16384
    # globe session size , if exceeded throws exceptions
    maxGlobalSessionSize = 512
    # file buffer size , if exceeded allocate new buffer
    fileWriteBufferCacheSize = 16384
    # when recover batch read size
    sessionReloadReadSize = 100
    # async, sync
    flushDiskMode = async
  }

}

启动seata
windows seata-server.bat
linux seata-server.sh

java实现定义Filter

获取前面一个服务传递过来的XID,

package io.app.filter;

import io.seata.core.context.RootContext;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Component;
import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

@Component
public class SeataFilter implements Filter {
    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        HttpServletRequest request = (HttpServletRequest)servletRequest ;
        HttpServletResponse response = (HttpServletResponse) servletResponse;
        String xid = request.getHeader(RootContext.KEY_XID) ;
        if(StringUtils.isNoneBlank(xid)){
            /*将这个xid绑定到,seata上下文中。当新的事务使用当前这个xid*/
            RootContext.bind(xid);
        }
        try {
            filterChain.doFilter(request , response);
        }finally {
            RootContext.unbind();
        }
    }
}

RestTemplate

如果多个Rest的化,都需要进行传递。

@Bean
    public RestTemplate restTemplate() {
        RestTemplate rest = new RestTemplate();
        List<ClientHttpRequestInterceptor>
                interceptors = new ArrayList<>();
        interceptors.add((request,bytes,execution) -> {
                String xid = RootContext.getXID();
                /*这里将xid通过header传递给下一个服务。*/
                request.getHeaders().add(RootContext.KEY_XID, xid);
                return execution.execute(request, bytes);
        });
        rest.setInterceptors(interceptors);
        return rest;
    }

java 配置文件

##file.conf
service {
  vgroupMapping.my_group = "default"
  default.grouplist = "127.0.0.1:8091"
}
##registry.conf
registry {
  type = "file" 
}

config {
  type = "file"  
  file {
    name = "file.conf"
  }
}

##application.properties 新增一个配置
# key是固定不变的,value要和 file.conf的 key vgroupMapping.my_group 中的 my_group一致
spring.cloud.alibaba.seata.tx-service-group=my_group

这里建议使用阿里巴巴的连接池,其他连接池可能会因为版本冲突,导致报错。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值