在JTA事务(使用容器管理的事务)中,显式查询的executeUpdate方法会立即提交 [英] Within JTA transaction (using container managed transaction), executeUpdate mehtod for explicit Query does immediate commit

查看:188
本文介绍了在JTA事务(使用容器管理的事务)中,显式查询的executeUpdate方法会立即提交的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在JBOSS 7.1 AS中,我正在使用容器管理的事务.对于每个请求,我都会进行几个实体更新.大多数实体使用EntityManager中的插入,合并,刷新"方法来管理更新.但是,有一个实体使用显式查询在数据库上执行"executeUpdate"(有关代码段,请参见下文).此sql更新将立即提交给数据库,并且与容器管理的事务不对齐(就像其他实体更新一样).无论如何,是否将明确的sql更新(下面的一个)与container-managed-transaction对齐?我正在尝试使回滚工作,并且此sql更新未回滚.除此一项外,所有其他实体更新和插入都可以正常工作.感谢您的所有帮助.

Within JBOSS 7.1 AS, I'm using container managed transaction. For each request, I do several entity updates. Most of the entities use "insert, merge, refresh" methods from EntityManager to manage the updates. However, there is one entity that uses explicit Query to do "executeUpdate" on the DB (see below for the code snippet). This sql update is immediately commited to the DB and it is not aligned with container managed transaction (like other entity updates). Is there anyway align explicit sql update (the one below) with container-managed-transaction? I'm trying to get rollback to work and this sql update is not being rolledback. All other entity updates and inserts are working fine except this one. Thanks for all your help.

代码段:

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的行为也相同)

Additional code: (Code below is using Bean-managed transaction, but i get same behaviour for CMT as well)

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

推荐答案

    • executeut命令在ut.commit被提交之前已提交给数据库 已执行

      The executeUpdate command gets committed to DB before ut.commit is executed

      它可能已经将更改刷新到数据库中,但是没有像在BMT中那样提交.

      It might have probably flushed changes into the database, but not committed as you were in BMT.

      您可以尝试回滚&验证它是否确实已提交&在交易中.

      You can try roll back & verify if it is really committed & is within transaction.

      以下仅在ResetValue上提交更改

      This below only commits changes on ResetValue

      当您执行本机查询或JPQL/HQL查询时,它将直接在数据库中进行更改& EntityManager可能不知道这些更改.

      When you execute native or JPQL/HQL query, it will make changes directly into the database & EntityManager might not be aware of those changes.

      因此,EntityManager不会隐式刷新受管实体&可能包含过时/过时的数据.

      Therefore managed entities aren't refreshed implicitly by EntityManager & might contain outdated/stale data.

      您可以浏览文档以获取更多详细信息,以下是摘录.

      You can go through documentation for more details, below is the exerpt.

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

      JPQL UPDATE queries provide an alternative way for updating entity objects. Unlike SELECT queries, which are used to retrieve data from the database, UPDATE queries do not retrieve data from the database, but when executed, update the content of specified entity objects in the database.

      使用UPDATE查询更新数据库中的实体对象可能是 比检索实体对象更有效率,然后 更新它们,但应谨慎使用,因为绕过了 EntityManager可能会中断与数据库的同步.为了 例如,EntityManager可能不知道缓存的实体 对象在其持久性上下文中已被UPDATE修改 询问.因此,优良作法是单独使用 用于UPDATE查询的EntityManager.

      Updating entity objects in the database using an UPDATE query may be slightly more efficient than retrieving entity objects and then updating them, but it should be used cautiously because bypassing the EntityManager may break its synchronization with the database. For example, the EntityManager may not be aware that a cached entity object in its persistence context has been modified by an UPDATE query. Therefore, it is a good practice to use a separate EntityManager for UPDATE queries.

    • 这篇关于在JTA事务(使用容器管理的事务)中,显式查询的executeUpdate方法会立即提交的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆