在JTA事务中(使用容器管理事务),显式Query的executeUpdate方法立即提交

时间:2015-02-18 16:21:15

标签: jpa jboss7.x entitymanager ejb-3.1 jta

在JBOSS 7.1 AS中,我使用容器管理的事务。对于每个请求,我会进行多次实体更新。大多数实体使用"插入,合并,刷新" EntityManager中的方法来管理更新。但是,有一个实体使用显式查询来执行" executeUpdate"在DB上(参见下面的代码片段)。此sql更新立即提交到数据库,并且未与容器管理事务(与其他实体更新一样)对齐。反正是否将显式的sql update(下面的那个)与container-managed-transaction对齐?我试图让回滚工作,这个sql更新没有被回滚。除此之外,所有其他实体更新和插入工作正常。谢谢你的帮助。

代码段:

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();

1 个答案:

答案 0 :(得分:0)

  •   

    在ut.commit之前,executeUpdate命令被提交到DB   执行

    它可能已经刷新了数据库中的更改,但没有像在BMT中那样提交。

    您可以尝试回滚&验证它是否真的提交了&在交易中。

  •   

    以下仅提交ResetValue

    的更改

    执行本机或JPQL / HQL查询时,它会直接对数据库进行更改。 EntityManager可能不知道这些更改。

    因此,管理实体不会被EntityManager& amp;隐式刷新。可能包含过时/陈旧的数据。

  • 您可以查看文档以获取更多详细信息,以下是exerpt。

      

    JPQL UPDATE查询提供了更新实体的替代方法   对象。与SELECT查询不同,SELECT查询用于从中检索数据   数据库,UPDATE查询不从数据库中检索数据,   但在执行时,更新指定实体对象的内容   数据库。

         

    使用UPDATE查询更新数据库中的实体对象可能是   比检索实体对象稍微高效一点   更新它们,但应谨慎使用,因为绕过了   EntityManager可能会中断与数据库的同步。对于   例如,EntityManager可能不知道缓存的实体   UPDATE修改了持久化上下文中的对象   查询。因此,使用单独的是一个好习惯   EntityManager for UPDATE查询。