直接用model的save和update方法不支持事务

如果在一个事务中调用model的save方法保存,事务不生效,即使事务失败,save方法仍然执行,请问一下这是为何? 如何才能在new IAtom声明的事务中使用model.save()方法保存

评论区

JFinal

2017-10-23 16:13

用的什么方式开启的事务?

datianxia

2017-10-26 19:54

用的new IAtom的方式启动的事务,代码如下:
boolean result = Db.tx(new IAtom() {
@Override
public boolean run() {
// 更新账户
User user = new User();
user.save();
// 更新order
LtOrder.dao.updatePrize(curPrize, ltOrderItem.getOrderId());

return true;
}
});


无论事务有没有报错,user.save()总是执行了,并没有回滚

JFinal

2017-10-27 15:39

@datianxia 需要有异常抛出,或者 return false , 异常才可能回滚

datianxia

2017-10-28 14:04

LtOrder.dao.updatePrize(curPrize, ltOrderItem.getOrderId());
这一段代码是有异常抛出的,我故意写的有异常的代码测试的。
如果把user.save改成直接写sql语句插入的方式,则整个事务会回滚,这个已经在代码里面做了多次验证,不知道是什么原因导致。
我看了源码,user.save()这一段用的connection和事务用的connection不是同一个,个人猜测是这个原因导致的

JFinal

2017-10-28 14:44

@datianxia 应该是你的事务级别不支持你当前的操作,将事务级调高到 4:
arp.setTransactionLevel(4);

如果你用的最新版本的 jfinal,默认就是这个级别的

JFinal

2017-10-28 14:46

user.save() 与 updatePrize(curPrize, ltOrderItem.getOrderId()); 如果开启了事务,就会用同一个 connection, 这个是在 jfinal 内部用 ThreadLocal 来保障的

JFinal

2017-10-28 14:47

发现你代码的一个严重错误:LtOrder.dao.updatePrize(curPrize, ltOrderItem.getOrderId());

dao 对象是全局共享的,只能用于查询,不能里头其它的 api,所以在现在的 jfinal demo 中的 dao 都这样来做的:
User dao = new User().dao();

注意,最后面调用了一次 dao() 方法,这样就可以天然避免你调用 update 方法了,相信你的 dao 对象在 new 出来的时候,没有调用这个 dao() 方法

热门反馈

扫码入社