- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在尝试实现两阶段原子提交或回滚模式。步骤是:
执行两个操作之一
a.在一个事务中提交多个更改b.回滚多个更改以放弃
这些步骤通过提交操作完成后效果很好,数据库读取,表单填充和更新,更改更新数据库。
当这些步骤通过回滚操作完成时,行为是相同的,除了在 userTransaction.rollback() 处抛出异常
[org.hibernate.engine.transaction.synchronization.internal.SynchronizationCallbackCoordinatorTrackingImpl](默认任务 30)HHH000451: 由后台线程调用的事务 afterCompletion;延迟 afterCompletion 处理,直到原始线程可以处理它。 [状态=4] (默认任务 30)sessionAbort ex org.hibernate.HibernateException:事务已在不同线程中回滚!
为什么我提交时没有抛出异常?表单的每个提交都有自己的线程,但我没有看到多线程问题。我不确定下一步该调查的重点在哪里。 MySql 或 Wildfly 或 JPA/Hibernate?
版本是:
Sudo 代码是:
@TransactionManagement(TransactionManagementType.BEAN)
@Stateful(mappedName = "testSession")
@SessionScoped
@TransactionAttribute(value = TransactionAttributeType.REQUIRED)
public class TestSession {
@PersistenceContext(unitName="MySqlXA",type=PersistenceContextType.EXTENDED)
private EntityManager entityManager;
@Resource private UserTransaction userTransaction;
First request/ thread one
userTransaction.begin();
Query query = entityManager.createQuery(sqlQuery);
List<SomeTable> queryResult = (List<SomeTable>)query.getResultList();
populate a SessionScoped ManagedBean
user think time
make updates through the UI and submit
Second request / thread two
TableOneRow tableOneRow = new TableOneRow(someStuff);
TableTwoRow tableTwoRow = entityManager.find(otherStuff);
entityManager.persist(tableOneRow);
entitymanager.merge(tableTwoRow);
Third request / thread three submit for commit
userTransaction.commit();
or Third request / thread three submit for abort
userTransaction.rollback();
提前致谢
最佳答案
通过进一步的研究和实验,看起来丢弃一组更新的最干净的方法是调用entityManager.clear()。
请参阅下面的三个测试日志和相关代码。第一组查找、更新、提交是我良好更新的基线。第二组 find、update、abort 导致 HHH000451 异常。最后一位是中止部分,但使用 EntityManager 清除。
2017-03-23 16:48:55,425 DEBUG [view.TestPage] (default task-21) find
2017-03-23 16:48:55,426 TRACE [ejb.session.TestPageSession] (default task-21) findNameAddress for addrId 5
2017-03-23 16:48:55,426 TRACE [ejb.session.TestPageSession] (default task-21) entityManager.find
2017-03-23 16:48:55,465 TRACE [ejb.session.TestPageSession] (default task-21) findNameAddress success true
2017-03-23 16:49:49,714 DEBUG [view.TestPage] (default task-24) update
2017-03-23 16:49:49,714 TRACE [ejb.session.TestPageSession] (default task-24) updateFirstLastName to One, For
2017-03-23 16:49:49,715 TRACE [ejb.session.TestPageSession] (default task-24) userTransaction.begin
2017-03-23 16:49:49,716 TRACE [ejb.session.TestPageSession] (default task-24) userTransaction.begin success true
2017-03-23 16:49:49,716 TRACE [ejb.session.TestPageSession] (default task-24) findNameAddress for addrId 5
2017-03-23 16:49:49,716 TRACE [ejb.session.TestPageSession] (default task-24) entityManager.find
2017-03-23 16:49:49,716 TRACE [ejb.session.TestPageSession] (default task-24) findNameAddress success true
2017-03-23 16:49:49,716 TRACE [ejb.session.TestPageSession] (default task-24) entityManager.merge
2017-03-23 16:49:49,721 TRACE [ejb.session.TestPageSession] (default task-24) updateFirstLastName success true
2017-03-23 16:50:19,652 DEBUG [view.TestPage] (default task-25) commit
2017-03-23 16:50:19,654 TRACE [ejb.session.TestPageSession] (default task-25) userTransaction.commit
2017-03-23 16:50:19,726 TRACE [ejb.session.TestPageSession] (default task-25) userTransaction.commit success true
2017-03-23 16:50:50,740 DEBUG [view.TestPage] (default task-26) find
2017-03-23 16:50:50,741 TRACE [ejb.session.TestPageSession] (default task-26) findNameAddress for addrId 5
2017-03-23 16:50:50,741 TRACE [ejb.session.TestPageSession] (default task-26) entityManager.find
2017-03-23 16:50:50,741 TRACE [ejb.session.TestPageSession] (default task-26) findNameAddress success true
2017-03-23 16:51:12,735 DEBUG [view.TestPage] (default task-29) update
2017-03-23 16:51:12,735 TRACE [ejb.session.TestPageSession] (default task-29) updateFirstLastName to two, For
2017-03-23 16:51:12,735 TRACE [ejb.session.TestPageSession] (default task-29) userTransaction.begin
2017-03-23 16:51:12,736 TRACE [ejb.session.TestPageSession] (default task-29) userTransaction.begin success true
2017-03-23 16:51:12,736 TRACE [ejb.session.TestPageSession] (default task-29) findNameAddress for addrId 5
2017-03-23 16:51:12,736 TRACE [ejb.session.TestPageSession] (default task-29) entityManager.find
2017-03-23 16:51:12,736 TRACE [ejb.session.TestPageSession] (default task-29) findNameAddress success true
2017-03-23 16:51:12,736 TRACE [ejb.session.TestPageSession] (default task-29) entityManager.merge
2017-03-23 16:51:12,736 TRACE [ejb.session.TestPageSession] (default task-29) updateFirstLastName success true
2017-03-23 16:51:40,888 DEBUG [view.TestPage] (default task-30) abort
2017-03-23 16:51:40,889 TRACE [ejb.session.TestPageSession] (default task-30) userTransaction.rollback
2017-03-23 16:51:40,890 WARN [org.hibernate.engine.transaction.synchronization.internal.SynchronizationCallbackCoordinatorTrackingImpl] (default task-30) HHH000451: Transaction afterCompletion called by a background thread; delaying afterCompletion processing until the original thread can handle it. [status=4]
2017-03-23 16:51:40,891 TRACE [ejb.session.TestPageSession] (default task-30) userTransaction.rollback success true
2017-03-23 16:54:08,623 DEBUG [view.TestPage] (default task-12) abort
2017-03-23 16:54:08,624 TRACE [ejb.session.TestPageSession] (default task-12) entityManager.clear
2017-03-23 16:54:08,625 TRACE [ejb.session.TestPageSession] (default task-12) entityManager.clear success true
package com.gregdata.session;
import javax.annotation.PostConstruct;
import javax.annotation.Resource;
import javax.ejb.Stateful;
import javax.ejb.TransactionAttribute;
import javax.ejb.TransactionAttributeType;
import javax.ejb.TransactionManagement;
import javax.ejb.TransactionManagementType;
import javax.faces.bean.SessionScoped;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.PersistenceContextType;
import javax.transaction.UserTransaction;
import org.jboss.logging.Logger;
import com.gregdata.model.Nameaddress;
@TransactionManagement(TransactionManagementType.BEAN)
@Stateful(mappedName = "localTestSession")
@SessionScoped
@TransactionAttribute(value = TransactionAttributeType.REQUIRED)
public class TestPageSession implements TestPageSessionLocal {
@PersistenceContext(unitName="MySqlStocksXA",
type=PersistenceContextType.EXTENDED)
private EntityManager entityManager;
@Resource private UserTransaction userTransaction;
private Nameaddress nameaddress;
private boolean transactionBegun;
private Logger logger;
public TestPageSession() {
logger = Logger.getLogger(this.getClass());
}
@PostConstruct
public void initialize() {
}
public EntityManager getEntityManager() {
return entityManager;
}
public Nameaddress findNameaddress(int addrId)
{
Nameaddress nameaddress = null;
boolean success = false;
logger.trace("findNameAddress for addrId "+addrId);
try {
logger.trace("entityManager.find");
nameaddress = entityManager.find(Nameaddress.class, addrId);
success = true;
} catch (Exception ex)
{
logger.warn("findNameAddress ex: "+ex.getMessage());
success = true;
}
logger.trace("findNameAddress success "+success);
return nameaddress;
}
public boolean updateFirstLastName(int addrId, String firstName, String lastName)
{
boolean success = false;
logger.trace("updateFirstLastName to "+firstName+", "+lastName);
try
{
beginTransaction();
nameaddress = findNameaddress(addrId);
if ( nameaddress == null)
{
throw new Exception("Nameaddress id "+addrId+" not found");
}
nameaddress.setFirstName(firstName);
nameaddress.setLastName(lastName);
logger.trace("entityManager.merge");
entityManager.merge(nameaddress);
success = true;
} catch (Exception ex)
{
logger.warn("updateFirstLastName ex: "+ex.getMessage());
success = false;
}
logger.trace("updateFirstLastName success "+success);
return success;
}
public boolean beginTransaction()
{
boolean success = false;
if (transactionBegun) return true;
logger.trace("userTransaction.begin");
try
{
userTransaction.begin();
success = true;
transactionBegun = true;
} catch(Exception ex)
{
logger.warn("userTransaction.begin ex "+ex.getMessage());
success = false;
}
logger.trace("userTransaction.begin success "+success);
return success;
}
public boolean commitTransaction()
{
boolean success = false;
logger.trace("userTransaction.commit");
try
{
userTransaction.commit();
success = true;
transactionBegun = false;
} catch(Exception ex)
{
logger.warn("userTransaction.commit ex "+ex.getMessage());
success = false;
transactionBegun = false;
}
logger.trace("userTransaction.commit success "+success);
return success;
}
public boolean abortTransaction()
{
boolean success = false;
logger.trace("userTransaction.rollback");
try
{
userTransaction.rollback();
success = true;
transactionBegun = false;
} catch(Exception ex)
{
logger.warn("userTransaction.rollback ex "+ex.getMessage());
transactionBegun = false;
success = false;
}
logger.trace("userTransaction.rollback success "+success);
return success;
}
public boolean clearEntityManager() {
boolean success = false;
logger.trace("entityManager.clear");
try {
entityManager.clear();
success = true;
} catch (Exception ex) {
logger.warn("clearEntityManager ex: "+ex.getMessage());
}
logger.trace("entityManager.clear success "+success);
return success;
}
}
关于java - UserTransaction.rollback 异常 HHH000451,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42847262/
我在spring事务中遇到了一个奇怪的问题。我的应用程序使用带有 EJB 的 Spring。 EJB 还调用带有 @Transaction 注释的 Spring 服务类。我使用 Spring JtaT
我在 tomcat 7 中运行我的应用程序时得到以下堆栈跟踪。相同的应用程序在 Weblogic AS 中运行良好。 15:31:48.896 [localhost-startStop-1] DEBU
我有一个带有 bean 管理事务的无状态 bean,以及一个像这样的方法: @Stateless @TransactionManagement(TransactionManagementType.BE
在下面的代码中,我尝试强制特定 bean 的事务超时,将其事务时间设置为短于该方法完成所需的时间。 超时设置为3秒,该方法完成所需的时间为5秒。 我正在使用可移植解决方案,它指的是 BMT 和使用 s
我有 Restful Webservice 实现。我在哪里通过注入(inject) @Resource 使用 UserTransaction 对象维护事务。而且我可以看到 UserTransactio
static void clean() throws Exception { final UserTransaction tx = InitialContext.doLookup("UserTra
这是一个学术问题;我没有与此相关的损坏代码。我只是想扩大我对幕后发生的事情的理解。 我在 JPA DAO 中为典型的 JSF Web 应用程序使用的代码模式(从书籍和教程中复制)基本上是这样的: pu
Java中有一段代码(一个循环)使用UserTransaction用于处理交易。 userTransaction 对象在循环之前声明,该对象声明为, private javax.ejb.Session
我有这门课: @RunWith(Arquillian.class) public class myIT { @Inject private UserTransaction utx;
我正在尝试实现两阶段原子提交或回滚模式。步骤是: 读取数据库并填充 UI 表单 在表单中输入更改,提交更新和应用程序级别验证 执行两个操作之一 a.在一个事务中提交多个更改b.回滚多个更改以放弃 这些
我有一个用于管理用户信息的 mySQL 数据库,我正在为我的 mySQL 数据库使用 JTA 数据源,这是 persistence.xml 的样子: java:/SensorCl
我在开发一个多模块 maven 应用程序并且 weblogic 已经在生产中。堆栈是: Tomcat 8.5 PostGre 9.6 hibernate 4.3.8 Spring 4.1.5 Spri
我有一个接受 POST 请求的 servlet,并且我正在尝试使用请求的参数来构建并保留实体类的实例。 这是我的 servlet: public class TheServlet extends Ht
标题说明了一切:UserTransaction 之间有什么区别?和一个 EntityTransaction ? 我的初步理解是 UserTransaction 在需要 JTA 时使用(例如,对多个事物
UserTransaction.getStatus() 方法总是返回值 '6',即使在执行回滚或提交之后也是如此。无法理解为什么状态没有改变。有人可以指出这里有什么问题吗? 我正在使用 WAS 6.1
为了在没有 Java EE 容器的情况下尝试 Java SE 中的声明式事务管理,我只是将 Glassfish 附带的事务 Servlet 示例转换为 Java SE。请参阅原始 Servlet 和随
需要帮助解决以下问题。 背景:我在独立应用程序中使用 OpenJPA 和 spring 3.x 从 db2 数据库检索数据。我不需要事务管理,因为我的要求只是从数据库读取数据。 请在我的 spring
以下代码中 ut 实例的重用是否正确? UserTransaction ut = (UserTransaction)ctx.lookup("java:comp/UserTransaction");
我已经阅读了 JTA JSR 一些时间,但我仍然不明白到底应该由谁来提供 UserTransaction 和 TransactionManager 接口(interface)的实现? JTA规范的内容
在 Wildfly 10:为什么我对 java:jboss/UserTransaction 和 java:/TransactionManager 有两种不同的 jndi 命名约定。看了 UserTra
我是一名优秀的程序员,十分优秀!