apache / incubator-seata

:fire: Seata is an easy-to-use, high-performance, open source distributed transaction solution.
https://seata.apache.org/
Apache License 2.0
25.35k stars 8.79k forks source link

MybatisPlus的基类insert方法不能回滚数据 #4556

Open iloveleeyan opened 2 years ago

iloveleeyan commented 2 years ago

问题如下:

seata(1.30和1.42版本都有)安装配置工作正常后,经测试发现,mybatis-plus 的 BaseMapper 类里的 insert 方法,如果在插入数据时,不指定主键id,会导致插入的数据无法回滚。同时更新的数据是能正常回滚的。

具体测试类看下图的那行注释:

public void insertOrder(int userId, int goodsId, String goods, int count) { GoodsOrder goodsOrder = new GoodsOrder(); // goodsOrder.setId(101); // 必须指定主键id,否则插入的记录不能回滚 goodsOrder.setUserId(userId); goodsOrder.setGoodsId(goodsId); goodsOrder.setGoods(goods); goodsOrder.setCount(count); goodsOrderMapper.insert(goodsOrder); }

这是插入后不能回滚的数据证据:

触发回滚: There was an unexpected error (type=Internal Server Error, status=500). [500] during [GET] to [http://BATIS-SEATA-FEIGN-STOCK/stock/update_stock?goodsId=56&count=101] [StockFeignService#insertOrUpdateStock(int,int)]: [{"timestamp":"2022-04-19T12:54:21.572+0000","status":500,"error":"Internal Server Error","message":"库存下限错误","path":"/stock/update_stock"}]

数据没被回滚,还在:

107 398 56 北欧沙发 101

如下操作可以正常回滚:
  1. 如果给实体实例设定id=101(即把该行注释去掉)
  2. 或者如果使用 mapper.xml 里的原生SQL语句

问题描述完了, 期待你的回复!谢谢哈!

funky-eyes commented 2 years ago

请提供有效日志及信息证明无法回滚,是undolog没生成,还是生成了回滚有脏数据,你的证据就是你抛了个异常而已,无法证明跟seata有直接关系

iloveleeyan commented 2 years ago

seata_gc.log 只有这个log 数据表的seata_undo_log 是空的,在发生了回滚错误后。

这个我能证明是seata导致的:

因为我搭好分布式事务的环境,3个微服务,seata运行起,经测试,添加注解 @GlobalTransactional 是能发生3个微服务的回滚的。而去掉注解@GlobalTransactional后就不能回滚了。证明seata是起作用的。

然后问题在这套环境里,调试,对其中一个没回滚成功的微服务,如果代码写成 goodsOrder.setId(101); 在insert,即手动设置insert数据的主键,是能正常回滚的。如果不设置,则没有回滚插入的数据。

这个推理很明显。

环境是 MybatisPlus 3.1.0,Mysql 5.7,nacos,spring-cloud,openfeign `

com.baomidou mybatis-plus-core 3.1.0 compile

`

建议你们也搭建个环境试试,这个不完全是seata的问题,应该是结合了mybatis plus后产生的。我对我搭建的环境测试了一晚都是如此。

SoloAlien commented 2 years ago

我也遇到上面的问题,没有指定主键的id时根本不走MySQLUndoLogManager中的insertUndoLog方法

caohdgege commented 2 years ago

请提供一下驱动版本

ftdmao commented 2 years ago

我是在整合tkmybatis的时候不插入undo_log。。。

caisf commented 4 months ago

的确存在这个问题。 mybatis-plus 在处理自增不指定id插入时,默认使用0让数据库自己处理。 不清楚是否这个原因? 各位有简单一点的解决方案吗(不改表id自增的情况)?