Hibernate 4.1.9(最新的最终版本)报告“不支持嵌套事务”
Posted
技术标签:
【中文标题】Hibernate 4.1.9(最新的最终版本)报告“不支持嵌套事务”【英文标题】:Hibernate 4.1.9 (latest final build) reporting `nested transactions not supported` 【发布时间】:2013-01-06 17:23:37 【问题描述】:我得到了一个
org.hibernate.TransactionException: nested transactions not supported
at org.hibernate.engine.transaction.spi.AbstractTransactionImpl.begin(AbstractTransactionImpl.java:152)
at org.hibernate.internal.SessionImpl.beginTransaction(SessionImpl.java:1395)
at com.mcruiseon.server.hibernate.ReadOnlyOperations.flush(ReadOnlyOperations.java:118)
引发该异常的代码。我从一个无限运行的线程调用flush,直到有数据要刷新。
public void flush(Object dataStore) throws DidNotSaveRequestSomeRandomError
Transaction txD;
Session session;
session = currentSession();
// Below Line 118
txD = session.beginTransaction();
txD.begin() ;
session.saveOrUpdate(dataStore);
try
txD.commit();
while(!txD.wasCommitted()) ;
catch (ConstraintViolationException e)
txD.rollback() ;
throw new DidNotSaveRequestSomeRandomError(dataStore, feedbackManager);
catch (TransactionException e)
txD.rollback() ;
finally
// session.flush();
txD = null;
session.close();
// mySession.clear();
编辑: 我在独立线程中调用刷新,因为数据存储列表包含数据。从我所看到的情况来看,它是对刷新的同步操作调用,因此理想情况下,刷新不应该在事务完成之前返回。我希望这样是我最不希望的。由于它是一个独立的线程来完成它的工作,我只关心它刷新是一个同步操作。现在我的问题是, txD.commit 是异步操作吗?它是否在该事务有机会完成之前返回。如果是,有没有办法在事务完成之前提交“等待”?
public void run()
Object dataStore = null;
while (true)
try
synchronized (flushQ)
if (flushQ.isEmpty())
flushQ.wait();
if (flushQ.isEmpty())
continue;
dataStore = flushQ.removeFirst();
if (dataStore == null)
continue;
try
flush(dataStore);
catch (DidNotSaveRequestSomeRandomError e)
e.printStackTrace();
log.fatal(e);
catch (HibernateException e)
e.printStackTrace();
catch (InterruptedException e)
e.printStackTrace();
编辑 2:添加了while(!txD.wasCommitted()) ;
(在上面的代码中),但我仍然觉得这该死的nested transactions not supported
。事实上,由于这个异常,表也没有写入记录。与表的类型有关吗?我的所有表都有 INNODB?
【问题讨论】:
我认为您开始交易两次,您可以尝试删除第二条语句txD = session.beginTransaction(); txD.begin() ;
已删除,结果相同。嵌套事务不支持异常。
好的,删除这两行并使用session.getTransaction()
获取事务实例并告诉我们。
顺便说一句,我刚刚在某处读到 begin 创建了一个新事务,而 getTransation 重用了旧事务。试试getTransaction(),几分钟后报告。
谢谢,您的提示帮助我进行了更多搜索并获得了适当的答案。
【参考方案1】:
终于修复了nested transaction not supported
错误。对代码所做的更改是
if (session.getTransaction() != null
&& session.getTransaction().isActive())
txD = session.getTransaction();
else
txD = session.beginTransaction();
//txD = session.beginTransaction();
// txD.begin() ;
session.saveOrUpdate(dataStore);
try
txD.commit();
while (!txD.wasCommitted())
;
以上代码也归功于Venkat。我没有找到 HbTransaction,所以只使用了 getTransaction 和 beginTransaction。它奏效了。
由于here 上的建议,我还对休眠属性进行了更改。我将这些行添加到了 hibernate.properties。仅此一项并不能解决问题。但我要把它留在那里。
hsqldb.write_delay_millis=0
shutdown=true
【讨论】:
嗨,正如你所说..在我的情况下,我根本没有打开Trasaction
我确定我只打开一次Transaction
但我仍然得到NestedTrasactionException
.. 可能是什么原因
Hibernate 非常敏感,编码时不要使用 java 基础。如果它有效,那就让它吧。上面的代码来自生产并且一直在工作。我只能说这些
好的,谢谢.. 我也会用你的代码来处理我的情况。【参考方案2】:
您可能在调用此方法之前已经开始了事务。
这应该是封闭事务的一部分,因此您不应该开始另一个;或者它不应该是封闭事务的一部分,因此您应该打开一个新会话和一个新事务,而不是使用当前会话。
【讨论】:
编辑了我的问题以添加更多细节和清晰度。请指教。 为了保持整洁,我已经提出了我的答案,但为了公平起见,我接受你的答案,因为你暗示我找到了正确的解决方案。谢谢。 @JB Nizet 嗨,正如你所说.. 就我而言,我根本没有打开Trasaction
我确定我只打开一次 Transaction
但我仍然得到 NestedTrasactionException
.. 什么可能是这个原因以上是关于Hibernate 4.1.9(最新的最终版本)报告“不支持嵌套事务”的主要内容,如果未能解决你的问题,请参考以下文章
hibernate 4.3 在使用获取数据获取不到数据库中最新变更的数据问题解决