一、该问题的重现步骤是什么?
下载seata1.4.2并启动(无注册中心,文件存储),修改LauncherConstant的seata ip地址,分别启动blade-seata-order、blade-seata-storage,按照示例操作可以提交、回滚;此示例没有体现分布式事务特点,完全是手动判断是否调用成功、手动抛出异常,而且是在调用方抛出,是一个简单的spring事务。
2. 测试2:只启动order(去除熔断类、去除手工抛异常),关闭storage,控制台没有报任何异常,事务竟然正常提交成功,订单表有了新数据,事务没有起到作用。
IStorageClient.java
@FeignClient(name = "blade-seata-storage") IStorageClient {
OrderServiceImpl.java createOrder
// if (cnt2 < 0) {
// throw new ServiceException("创建订单失败");
// } else if (count > maxCount) {
// throw new ServiceException("超过订单最大值,创建订单失败");
// }
http://localhost:8501/order/create?userId=1&commodityCode=product-2&count=1
{"code":400,"success":false,"data":{},"msg":"操作失败"}
3.测试3:在上面的基础上,把storage启动,提交订单还是成功了(控制台有异常,页面显示失败,但订单表有了新数据)。
java.lang.RuntimeException: 超过库存数,扣除失败!
http://localhost:8501/order/create?userId=1&commodityCode=product-2&count=1
{"code":400,"success":false,"data":{},"msg":"操作失败"}
二、你期待的结果是什么?实际看到的又是什么?
期待结果:被调用方异常时回滚事务
实际看到:被调用方异常或未启动,对事务没有任何影响,完全不起作用
三、你正在使用的是什么产品,什么版本?在什么操作系统上?
bladex2.9
windows10
四、请提供详细的错误堆栈信息,这很重要。
五、若有更多详细信息,请在下面提供。
通过Gateway进行调用试试
网关也不行,问题依旧;怀疑是全局捕获异常导致的
访问网关:
http://192.168.12.51/blade-seata-order/order/create?userId=1&commodityCode=product-2&count=1
返回结果:
{"code":400,"success":false,"data":{},"msg":"操作失败"}
tb_order表:
iduser_idcommodity_codecountmoney
591product-215
601product-215
在仔细看了一下你说的内容,这里要和你说明一下
1. order和storage是两个不同的服务,两者入库是通过order调用storage的feign服务来处理的,如果feign异常则会通知seata,seata再通知order以此来实现分布式事务回滚。这个流程并不是简单的spring事务,并且seata官方也是用的这个例子,他们不肯跟犯这么低级的错误。另外你可以在回滚的时候查看控制台日志,seata是有详细的commit和rollback日志的。
2. 你手动取消了抛异常,整个流程没有feign失败的场景,自然不会触发分布式事务。
“你手动取消了抛异常,整个流程没有feign失败的场景? ”
库存服务都没启动,还不算异常?
库存服务都报异常了,还不算异常?
异常肯定发生了,手动取消的是被调用方,用户一个业务可能要调用n个微服务,主方法怎么会知道哪个微服务出问题了,要主方法一个一个去判断,然后手动抛出异常,很不合理,工作量也很大。
seata官方示例我看了,它是在库存服务抛出的异常,不是在订单;而bladex-biz是在订单抛出异常;不管在哪里抛出,都应该能回滚才对。
扫一扫访问 Blade技术社区 移动端