gpt4 book ai didi

java - UserTransaction.rollback 异常 HHH000451

转载 作者:行者123 更新时间:2023-11-29 19:14:17 26 4
gpt4 key购买 nike

我正在尝试实现两阶段原子提交或回滚模式。步骤是:

  1. 读取数据库并填充 UI 表单
  2. 在表单中输入更改,提交更新和应用程序级别验证
  3. 执行两个操作之一

    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?

版本是:

  • java 版本“1.7.0_07”
  • ejb3
  • wildfly-8.2.0.Final
  • mysqladmin 版本 8.42 Distrib 5.5.21,适用于 x86_64 上的 Linux
  • RichFaces 4.5.4
  • 使用方言:org.hibernate.dialect.MySQL5Dialect

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/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com