如何强制将新记录立即保存到数据库*?

时间:2013-02-13 12:42:31

标签: java hibernate transactions glassfish seam

我正在开发一个带有两个线程的Java / Seam / Hibernate / Glassfish应用程序:

  • 线程#1 发送各种消息并将摘要信息写入MySQL数据库。
  • 线程#2 定期轮询数据库(由ScheduledExecutorService调用)并对每条消息的当前“状态”进行操作。

遇到了集成测试问题:线程#2 等待线程#1 添加新行的时间似乎并不重要,它只是在测试期间没有添加,因此没有进行预期的调用。那么可以肯定的是,在测试失败后会弹出一个新行 - 但为时已晚。不确定这可能是设计问题 - 线程#2 目前使用Lifecycle.beginCall()...Lifecycle.endCall()获取Seam上下文。所以我的理解(这可能是错误的)可能是问题是由于两个线程有​​两个单独的Hibernate会话 - 所以一个阅读不知道一个写作的最新信息?

可能有不同的方法来解决这个问题,但我当前的想法是,我不能强迫Hibernate在我调用save() / flush()时甚至手动提交时立即向表中添加记录交易?没有任何好运 - 让我想知道幕后是否有某种托管交易。感谢任何建议......

有关信息,这里是添加记录的代码的要点:

// Obtain Hibernate session
Session session = (Session) Component.getInstance("hibernateSession");

// Create request
Request newRequest = new Request();
// newRequest.set<blah>();

// Save the new request to the database
session.save(newRequest);

// Have tried session.flush(), transaction.commit() etc. here.
// Nothing seems to put the record into the database straight away.

不确定这是否相关,但这是Hibernate配置:

<property name="transaction.flush_before_completion">true</property>
<property name="connection.release_mode">after_statement</property>
<property name="transaction.manager_lookup_class">org.hibernate.transaction.SunONETransactionManagerLookup</property>
<property name="transaction.factory_class">org.hibernate.transaction.JTATransactionFactory</property>
<property name="current_session_context_class">jta</property>

(由于这是客户拥有的现有应用程序,我无权更改Hibernate配置。)

2 个答案:

答案 0 :(得分:1)

你的猜测很好。

您正在使用JTATransactionFactory,因此交易由JTA划分(即由容器划分)。

用于保存Request的方法(此处我认为它是在EJB中定义的)需要使用事务注释进行注释:@TransactionAttribute(TransactionAttributeType.REQUIRES_NEW),因此当方法结束时,事务处理得到承诺。

答案 1 :(得分:0)

非常感谢@Carlo Pellegrini,他的回答指出了我正确的方向。我已经遇到this answer并在save()操作后尝试了以下代码:

// Commit Seam-managed transaction (if there is one)
UserTransaction userTransaction = (UserTransaction) Component.getInstance("org.jboss.seam.transaction.transaction");
if (userTransaction.isActive()) {
    userTransaction.commit();
}

嗯,它做得很好,但我不喜欢它 - 似乎有点hacky!还有更好的方法吗?