两个service事务统一_分布式环境下事务的安全性

7e43d008318b3512bea77e7c2a342080.png

一、话不多说,先上结论

69e6ef2dbc94cd5a474b31e898ccf974.png

二、业务场景概述

08c486e3e3ed5412a2148f1245a34f40.png

问题概述

如何保证A订单系统和B物流系统中订单的当前状态保持一致?

实战演练代码

client-service

为了更好的测试在分布式环境下可能存在的问题,测试前我们先把连接池的最大连接数,改小一点,如下是修改Durid的这两个配置:

6242418ce9df1a677644741db787d475.png

controller

688feb7279dca49604da985e194c66e5.png

service

fbe3c894f3042f364862c8aa6a2296e9.png

target-service

controller

1d06b791925b00945a33e455dde4d69c.png

2. 使用Spring自带的事务注解

在一定程度上可以保证数据的一致性,但是无法成熟较大的访问量

存在数据库连接数超出,系统崩溃的风险

实战演练

测试前准备

1、配置连接池最大连接数为2

2、为发货方法添加@Transactional注解

测试操作

1、调用订单发货接口,发货订单2

2、同时调用订单发货接口,发货订单3

3、前两者发货请求执行过程中,同时调用订单查询接口

测试结果

订单1查询接口报错

错误提示

数据库连接池中的连接不足,超过最大连接数

原因分析

1、发货操作需要调用其他系统进行处理,中间存在一定的时间间隔

2、为发货操作添加事务保证数据一致性,但是整个操作在其他系统没有返回结果之前,每个发货操作都会占用一个数据库连接

3、综上分析,多个发货操作下,连接数超出最大允许数量是肯定的

三、使用编程事务

实现方案简述

1、在系统A中引入中间状态

2、发货请求收到以后,将该订单状态更新为中间状态,这一步操作添加事务

3、无事务状态请求B系统进行发货操作

4、B系统请求成功后,将订单状态更新为结果状态,这一步操作单独添加另一个事务

5、特殊情况处理:假如B系统出现故障,部分订单更新至中间状态,可使用调度系统执行一个job,统一对这部分订单进行B系统发货操作状态同步

实战演练

在基础代码上更新的内容

dbbc64522c5fbdbae2eb125ad0980819.png

OrderServiceImpl更新内容

a853e47a737bf0758adfaad3c7420cce.png

测试操作

同Spring事务测试步骤

运行结果

订单1可一正常查询

订单2、订单3发货操作与订单1查询操作无影响

小结

使用编程事务减少了数据库连接的占用与消耗

大大提高了系统心梗,减少了数据库连接资源的浪费

不足之处

当用户高频或者误触,多次请求发货操作或这下订单操作的时候

存在想B系统发送多个重复下订单的请求

实战演练

0a698c41fd8268ef17ff2ed8fadde018.png

测试结果

d737d683a16927af9093a20c743f8a42.png

分析:由于用户请求次数过多,导致在短时间内向物流发货接口发出了许许多重复的请求,这样就会导致在物流系统中接受到相同的订单发货请求,如果不进行幂等性处理,可能会造成数据错乱的风险。

四、编程事务的进一步优化


CAS锁(基于状态机的乐观锁)

对于编程事务中出现的高频请求下的异常情况,也就是幂等性问题,此处介绍一种比较简单的解决方案来实现服务调用的幂等性

CAS锁

类似于ReentrantLock的实现原理

此处就是为数据添加一个版本好,也可以称呼为状态

更新操作前查询数据,获取到旧数据的版本号

更新数据的时候以查询数据时版本号和此时数据库中版本号的关系作为能否更新数据的条件

实战演练

7d2f5d41c88184e4fc522889762c9dfd.png

updateSql

edf5f18c216c6e7f2015164d85111613.png

总结

基于状态机的乐观锁,在一定程度上可以解决重复订单的问题

想看更多精彩好文微信搜索“小白笔记之Java专刊”,让我们一起遨游与技术的海洋

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值