Service注入事务拦截器问题

@Clear(Tx.class)
public String forceToComplete() {
    //此处有一个循环,目的是循环中的更新操作互相不影响
    updateStockInOrderToDelete();
}
@Before(Tx.class)
private void updateStockInOrderToDelete() {
    Db.update("insert into temp_test values ('test')");
    int s = 1/0;
}

我的service整个业务层都在Config中注入了事务,所以第一个方法中清除Tx.class,我想问下为什么update中重新租入Tx.class, 不生效。出异常时事务没有回滚。

必须要如下写法才会回滚

Db.tx(() -> {
    updateStockInOrderToDelete();
    return true;
});

评论区

JFinal

2019-10-31 19:01

注意业务层的拦截器被触发,需要开启 me.setInjectDependency(true) 并且在 Controller 中使用 @Inject 将业务层注入到控制层

如果不使用上面的方式,触发拦截器还可以使用 Aop.get(...)

controller 层的 AOP 是自动触发的,无需上述的方式

JFinal

2019-10-31 19:01

总之,当前我怀疑你的事务拦截器并没有被触发

hb963724769

2019-11-01 08:57

@JFinal forceToComplete这个方法在controller,updateStockInOrderToDelete这个方法在Service业务层,不是controller里面的方法,不clear的话,异常情况数据库没有插入数据,说明事务是开启的,Config中已经配置了me.setInjectDependency(true)。

JFinal

2019-11-01 11:34

@hb963724769 先要确保拦截器本身已经被触发

hb963724769

2019-11-02 12:07

@JFinal 业务层的拦截器的触发条件是不是说,先在业务层使用@before方法注入拦截器,然后再controller控制层使用@Inject注入,并且控制层必须要有 service.方法名 调用这个方法,这个方法的拦截器才会被触发。

如果这个业务层的方法,是被业务层的其他方法调用的,那么这个方法的拦截器就无法触发。

JFinal

2019-11-02 16:05

@hb963724769 前半部分是对的,后半部分是错误的,业务层其它方法调用也可以触发拦截器

业务层拦截器的触发简单来说就是两种:
1:在 controller 中通过 @Inject 注入
2: 通过 Aop.get(...) 获取的对象

hb963724769

2019-11-04 09:48

@JFinal updateStockInOrderToDelete方法从private改成public后可以注入Tx拦截器

JFinal

2019-11-04 10:38

@hb963724769 只有 public 方法才能被拦截