Jpa 在JTA事务中(使用容器管理的事务),显式查询的executeUpdate方法会立即提交
在JBoss7.1AS中,我使用的是容器管理的事务。对于每个请求,我都会进行几个实体更新。大多数实体使用EntityManager中的插入、合并和刷新方法来管理更新。但是,有一个实体使用显式查询在DB上执行更新。代码段请参见下文。此sql更新将立即提交给DB,并且与其他实体更新一样,它与容器管理的事务不一致。下面的sql更新是否与容器管理的事务保持一致?我正在尝试回滚,但此sql更新没有回滚。除此之外,所有其他实体更新和插入都可以正常工作。谢谢你的帮助 代码段:Jpa 在JTA事务中(使用容器管理的事务),显式查询的executeUpdate方法会立即提交,jpa,jboss7.x,entitymanager,ejb-3.1,jta,Jpa,Jboss7.x,Entitymanager,Ejb 3.1,Jta,在JBoss7.1AS中,我使用的是容器管理的事务。对于每个请求,我都会进行几个实体更新。大多数实体使用EntityManager中的插入、合并和刷新方法来管理更新。但是,有一个实体使用显式查询在DB上执行更新。代码段请参见下文。此sql更新将立即提交给DB,并且与其他实体更新一样,它与容器管理的事务不一致。下面的sql更新是否与容器管理的事务保持一致?我正在尝试回滚,但此sql更新没有回滚。除此之外,所有其他实体更新和插入都可以正常工作。谢谢你的帮助 代码段: entityManager.cr
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();
executeUpdate命令在执行ut.commit之前提交到DB
执行
它可能已将更改刷新到数据库中,但没有像在BMT中那样提交
您可以尝试回滚并验证它是否真的已提交以及是否在事务中
以下内容仅提交对ResetValue的更改
当您执行本机或JPQL/HQL查询时,它将直接对数据库进行更改&EntityManager可能不知道这些更改
因此,EntityManager不会隐式刷新托管实体&可能包含过时/过时的数据
您可以通过文档了解更多详细信息,下面是练习
JPQL更新查询提供了一种更新实体的替代方法
物体。与SELECT查询不同,SELECT查询用于从中检索数据
数据库、更新查询不从数据库检索数据,
但在执行时,更新中指定实体对象的内容
数据库
可能需要使用更新查询更新数据库中的实体对象
比检索实体对象然后
更新它们,但应谨慎使用,因为绕过
EntityManager可能会中断与数据库的同步。对于
例如,EntityManager可能不知道缓存的实体
对象在其持久性上下文中已被更新修改
查询因此,使用单独的
更新查询的EntityManager
尝试添加一些相关的代码,我做了几个实体更新。大多数实体使用insert、merge、refresh,因此不清楚如何更新实体&您如何得出大多数实体使用insert、merge、refresh等的结论。使用哪个JPA实现?我添加了一些附加代码。我正在使用JPA2.0的Hibernate实现。org.hibernate:hibernate entitymanager:4.2.7.sp1非常感谢您的帮助。我被这个问题困扰了一段时间。谢谢你的回复!我发现了这个问题。这与JBoss7.2问题有关,无法通过UI更新数据源页面上的JTA选项。我认为在persistence.xml上配置transaction type=JTA就足够了。然而,我错了。当我手动更新standalone.xml并重新启动JBOSS时。当CMT提交其余事务时,显式查询正在提交。s感谢您的帮助!