直接用Db.update有时候不执行

List<String> msgs = new ArrayList<String>();

boolean result = Db.tx(new IAtom() {

@Override

public boolean run() throws SQLException {

try {

//Db.update("update t_active_code set customer_id=?, account_id=?, used=? where id=?", user.getCustomerId(), user.getId(), 1, activeCode.getId());

ActiveCode updateCode = new ActiveCode();

updateCode.setCustomerId(user.getCustomerId());

updateCode.setAccountId(user.getId());

updateCode.setUsed(1);

updateCode.update();

//Db.update("update t_customer set order_level = order_level+1 where id=?", user.getCustomerId()); 

Customer customer = CustomerService.me.findById(user.getCustomerId());

Customer updateC = new Customer();

updateC.setId(customer.getId());

updateC.setId(customer.getOrderLevel()+1);

updateC.update(); 

这里不执行,导致业务大量出错,因为我用了大量的Db.update();

评论区

JFinal

2018-09-29 16:33

注意一个核心问题,你的这段数据库操作代码全部处在一个事务中,如果后方数据库操作代码依赖于前方代码对数据库产生的影响就要格外注意

因为你上述多次操作数据库的所有代码处于一个事务中,所以事务提交之前数据库表中的数据是不会有任何变化的,而你靠后的数据库操作的 where 条件却依赖了这些变化,造成 where 条件实际上为 false, 最后看到的现象是数据库数据的变化不如自己预期

你可以将后方所依赖的数据库操作代码挪一部分到事务之前去,就能看到效果了

这个是 JDBC 事务的行为,jfinal 从来不会干预

tuxming

2018-09-29 17:02

我这里红色的是没更改之前的代码, new 的对象在update是现在的代码,现在的代码执行是没有问题的。

tuxming

2018-10-01 12:27

经测试,其他用Db.update的地方都会偶尔出这个问题。

tuxming

2018-10-07 13:40

最近还出现一个问题,我调试了一个星期,得到的答案是Db.update("update table set status = 6 where id in (,,,,)"), 却update了整个表,我不管怎么弄,都是update的整个表,但是我改成,new Object().setId().setStatus()正常,我都快哭了。。。。

JFinal

2018-10-07 14:38

@tuxming Db.update("update table set status = 6 where id in (,,,,)"), update了整个表,这个很可能是 JDBC 驱动的 bug,深度升级一下 JDBC

而 jfinal 在底层是直接调用的 JDBC,如果你的 sql: "update table set status = 6 where id in (,,,,)" 真的更新了整个表,那一定是 JDBC 的行为,因为 jfinal 是从来不执行任何 sql 的

进一步讲,你的 sql 中的 where id in (,,,,) 片段肯定是错误的,JDBC 应该直接报异常才对

建议使用 jfinal 的 sql 管理功能,生成正确的 where id in (a, b, c, d) 片段,具体看一下这里:
http://www.jfinal.com/doc/5-13

JFinal

2018-10-07 14:39

@tuxming 最后,这类问题一定要使用单步调试,看看底层发生了什么,要看现场,不要猜测问题的原因,如果能猜到,那也就不会有你碰到的这些问题了

tuxming

2018-10-07 18:39

好的,谢谢大佬,代码片段就是更正后的意思,。。,我再跟进,主要最近弄得我头大,因为这个问题本地无法重现,生产环境才会出现,然后不停的打log,不停注释相关代码,最后把这行代码注释掉,就正常了,但是定时任务必须要有,所以只能解决,不能逃避。。。。痛苦啊,不过大佬国庆都还在混社区,也是够累的,

tuxming

2018-11-01 17:13

结贴,经过多方测试,是同事埋下的坑,这里让我一度怀疑jfinal, 对不起波总。

JFinal

2018-11-01 17:15

@tuxming jfinal 的数据库操作部分仅仅是对 JDBC 进行了一个极薄封装,在本质上就是将你的 sql + para 直接扔给了底层的 JDBC,想要出错都是很困难的,因为 JDBC 是很稳固的

热门反馈

扫码入社