大家好,又见面了,我是你们的朋友全栈君。
当前依赖,全局事务XID,不需要手动进行绑定,自动进行传递
<dependency>
<groupId>com.alibaba.cloud</groupId>
<!–加入spring-cloud-alibaba-seata,解决xid不传递问题–>
<artifactId>spring-cloud-alibaba-seata</artifactId>
<version>2.2.0.RELEASE</version>
<exclusions>
<exclusion>
<groupId>io.seata</groupId>
<artifactId>seata-spring-boot-starter</artifactId>
</exclusion>
<exclusion>
<groupId>io.seata</groupId>
<artifactId>seata-all</artifactId>
</exclusion>
</exclusions>
</dependency>
全局事务XID需要通过过滤器或拦截器进行手动绑定,否则下游服务获取不到全局XID回滚不了
<dependency>
<groupId>io.seata</groupId>
<artifactId>seata-spring-boot-starter</artifactId>
<version>1.3.0</version>
<!-- 这里需要排除自身的seata-all -->
<exclusions>
<exclusion>
<artifactId>seata-all</artifactId>
<groupId>io.seata</groupId>
</exclusion>
</exclusions>
</dependency>
<!-- 导入与之前下载的seata版本一致的包 -->
<dependency>
<groupId>io.seata</groupId>
<artifactId>seata-all</artifactId>
<version>1.3.0</version>
</dependency>
OpenFeign进行手动传递XID
@Component
public class FeignConfiguration implements RequestInterceptor {
@Override
public void apply(RequestTemplate requestTemplate) {
requestTemplate.header("XID", RootContext.getXID());
}
}
提供者手动绑定XID
@Component
public class SeataFilter implements Filter {
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
HttpServletRequest request = (HttpServletRequest) servletRequest;
//手动绑定XID
String xid = request.getHeader("XID");
if(StringUtils.isNotBlank(xid)){
RootContext.bind(xid);
}
filterChain.doFilter(servletRequest,servletResponse);
}
}
seata在1.0.0版本之后就不需要手动进行数据源代理,已经被自动代理
客户端的配置文件
seata:
enabled: true
tx-service-group: my_first_seata #配置文件中的事务服务组一样
config:
type: nacos # nacos中拉去对应的配置文件
nacos:
server-addr: 192.168.60.46:8849
group: SEATA_GROUP
registry: # 会去nacos中拉去seata-server服务
type: nacos
nacos:
application: seata-server
server-addr: 192.168.60.46:8849
group: SEATA_GROUP
seata1.0.0之后config文件下就移除了nacos-config.txt等文件,改为了config.txt需要手动下载,并且config.txt需要在nacos-config.sh的上一级目录下才能推送到nacos中
# 只需要修改下面几种配置即可,这里是配置客户端需要拉取的配置文件
service.vgroupMapping.自定义的名称=default
store.mode=db #修改为db
store.db.dbType=mysql #修改msql的连接方式账号和密码
阶段一:业务SQL:update product set name = ‘GTS’ where name = ‘TXC’
业务数据和回滚日志记录会在同一个本地事务中保存,会释放本地锁和连接资源
阶段二(回滚):
通过一阶段的回滚日志进行反向补偿
阶段二(提交):
一阶段提交本地事务,必须需要拿到更改数据的全局锁,拿不到全局锁,不能提交本地事务,超出等待时间,会回滚本地事务,释放本地锁
例:tx1和tx2两个全局事务同时修改 a表的m字段,m初始为1000;
tx1先开始,拿到本地锁,将m 1000-100 = 900。本地事务提交前,先拿到该记录的全局锁,本地提交释放本地锁。tx2开始,拿到本地锁,将m 900-100=800,提交本地事务前,先获取该记录的全局锁,tx1全局事务提交前,全局锁会被tx1所持有,tx2就会重试等待全局锁。
tx1二阶段全局提交,释放全局锁。tx2拿到全局锁提交本地事务。如果tx1二阶段为全局回滚,那么会重新重试获取本地锁,此时tx2如果还在等待全局锁,同时持有本地锁,tx1分支事务就会等待tx2超时释放本地锁之后,再次获取本地锁;整个过程 全局锁都是被 tx1锁持有,不会存在脏数据的问题
Seata AT模式的默认全局隔离级别是读未提交,如果在特定场景下,必需要求全局的读已提交,Seata采用通过select for update 语句来进行代理的;select for update语句的执行会申请全局锁 ,如果全局锁被其它事务锁持有,就会回滚select for update的本地执行并且重试,因为这时候查询是被锁住,直到全局锁拿到,即读取相关的数据是已提交的
AT模式是基于本地支持ACID事务的关系型数据库:
相应的TCC模式,不依赖本地底层数据的事务支持:
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
发布者:全栈程序员栈长,转载请注明出处:https://javaforall.cn/191921.html原文链接:https://javaforall.cn
扫码关注腾讯云开发者
领取腾讯云代金券
Copyright © 2013 - 2025 Tencent Cloud. All Rights Reserved. 腾讯云 版权所有
深圳市腾讯计算机系统有限公司 ICP备案/许可证号:粤B2-20090059 深公网安备号 44030502008569
腾讯云计算(北京)有限责任公司 京ICP证150476号 | 京ICP备11018762号 | 京公网安备号11010802020287
Copyright © 2013 - 2025 Tencent Cloud.
All Rights Reserved. 腾讯云 版权所有