波总,请问下我用Db.tx(new IAtom())事物

image.png

Db.tx根据true和false来控制是否回滚,但是我怎么在外部获取到是否回滚了呢?因为我不知道是否提交成功,所以没办法给前端返回是否提交成功的信息

评论区

JFinal

2018-01-26 21:09

最简单的办法是下面的办法获取到一个 boolean 来判断:
boolean ret = Db.tx(...);

还可以通过使用下面的方式来返回很多数据:
1:final Ret ret = new Ret();
2:在 Db.tx 的 run() 方法中直接操作 ret 这个对象,例如:
ret.set("isRollback", true);
ret.set("isCommit", false);

注意上面的 Ret 对象前面需要使用 final 关键字

没有顺风的船

2018-01-27 13:04

好的,谢谢波总解答

成陈

2019-06-12 17:09

波总 我想问下 为啥 boolean ret = Db.tx(...); ret结果为false 还是提交成功了 线上环境 有时候会出现这种情况,想知道是可能是什么原因呢?

JFinal

2019-06-12 22:46

@成陈 事务问题比较复杂,如果你用的 mysql , 首先要检查当前 table 是不是 InnoDb 引擎,myisam 引擎不支持事务

然后,你的 Db.tx 中有没有吃掉过异常,也就是说有没有 try catch,并且没有再次抛出异常

然后,Db.tx 中的数据库操作是不是将数据从数据库读到内存,然后在内存中操作,再写回数据库,这种操作需要的事务级别较高,例如:
Db.tx(...
int cash = Db.queryInt("select cash from account where id = ?", 123);
cash = cash + 100;
Db.update("update account set cash = ? where id = ?", cash, 123);
return true;
);

由于上面操作 cash 字段是先读到内存中进行,然后再存回数据库,所以需要的事务级别很高,否则会现现幻读

改进的办法是:
Db.tx(...
Db.update("update account set cash = cash + 100 where id = ?", 123);
return true;
);

也就是说,所有真正的数据操作全交给了数据库,不经过内存

热门反馈

扫码入社