在JTA事务(使用容器管理的事务),executeUpdate的mehtod显式查询并立即提交(Wi

2019-10-21 22:39发布

在JBOSS 7.1 AS,我使用的容器管理事务。 对于每个请求,我做的几个实体进行更新。 大多数实体使用“插入,合并,刷新”从EntityManager的方法来管理更新。 然而,存在使用明确的查询做“executeUpdate的”关于DB一个实体(请参见下面的代码片段)。 这个SQL更新会立即将提交给DB和它不与容器管理的事务(如其他实体更新)对齐。 反正是有对准容器管理事务的明确SQL更新(下一个)? 我试图让回滚工作,这个SQL更新没有被rolledback。 所有其他实体的更新和插入,除了这一个是工作的罚款。 感谢你的帮助。

代码片段:

entityManager.createQuery 
 ( "UPDATE Balance a SET a.balanceValue = :newValue WHERE a.balanceId =:balanceId AND a.balanceValue = :currentValue" ) .setParameter("balanceId", cb.getBalanceId()) .setParameter("currentValue", cb.getBalanceValue()).setParameter("newValue", newAmt).executeUpdate();

附加代码:(下面的代码是使用Bean管理的事务,但我得到同样的行为CMT以及)

            ut.begin();
        ChargingBalance bal2 = entityManager.find(ChargingBalance.class, 13);
        bal2.setResetValue((new Date()).getTime());
        String UPDATE_BALANCE_AND_EXPIRYDATE_EQUAL = "UPDATE ChargingBalanceValue a"
                + "  SET a.balanceValue = :newValue "
                + "  WHERE a.balanceId = :balanceId";

        Query query = entityManager.createQuery(UPDATE_BALANCE_AND_EXPIRYDATE_EQUAL)
                .setParameter("balanceId", 33)
                .setParameter("newValue", 1000l);

        /*The executeUpdate command gets committed to DB before ut.commit is executed */
        query.executeUpdate();

        /* This below only commits changes on ResetValue */
        ut.commit();

        ut.begin();
        ChargingBalance bal = entityManager.find(ChargingBalance.class, 23);
        bal.setResetValue(1011l);

        query = entityManager.createQuery(UPDATE_BALANCE_AND_EXPIRYDATE_EQUAL)
                .setParameter("balanceId", 33)
                .setParameter("newValue", 2000l);
        query.executeUpdate();

        /* This rollback doesn't rollback changes executed by executeUpdate, but it rollbacks ResetValue change */
        ut.rollback();

Answer 1:

  • 在执行之前ut.commit使用executeUpdate命令获取致力于DB

    它也许可能已经改变刷新到数据库中,但你在BMT没有承诺。

    您可以尝试回滚和确认其是否真正致力于&是事务中。

  • 这仅低于上提交修改ResetValue

    当您执行本地或JPQL / HQL查询,它将直接更改到数据库和EntityManager的可能不知道这些变化。

    因此,管理实体不被EntityManager的含蓄清新及可能包含过时/陈旧的数据。

  • 你可以通过文档了解更多信息,下面是exerpt。

    JPQL UPDATE查询提供更新的实体对象的另一种方式。 不同于SELECT查询,这是用来从数据库中检索数据,UPDATE查询不从数据库中检索数据,但在执行时,更新指定的实体对象在数据库中的内容。

    更新实体在使用UPDATE查询可以稍微比检索实体对象,然后更新它们更有效率的数据库对象,但是应该小心使用,因为绕过EntityManager的可能会破坏其与数据库的同步。 例如,所述的EntityManager可能不知道在其持久性上下文高速缓存的实体对象已经由UPDATE查询修改。 因此,使用单独的EntityManager为UPDATE查询一个很好的做法。



文章来源: Within JTA transaction (using container managed transaction), executeUpdate mehtod for explicit Query does immediate commit