我有一个Spring管理的网络应用,我们正在使用Hibernate。在我的hibernate.cfg.xml
我们有
<property name="hibernate.current_session_context_class">thread</property>
它还配置为使用HikariCP连接池。
当我们打开会话时,我们遵循这个范例。请注意,我没有明确关闭会话。
Transaction tx = null;
Session session = sessionFactory.getCurrentSession();
try {
tx = session.beginTransaction();
// do DB stuff.
tx.commit(); // or, sometimes session.getTransaction().commit();
} catch (Exception e) {
if (tx != null) {
tx.rollback();
}
throw new CustomDbException(e);
}
在某些情况下,在关闭会话时,我们至少会session.getTransaction().commit()
,这是不存在的,但我不确定它是否会给出不同的交易或导致某些问题。
我们一直看到LockAcquisitionException: could not execute statement
,StaleObjectStateException: Row was updated or deleted by another transaction (or unsaved-value mapping was incorrect)
和TransactionException: nested transactions not supported
出现间歇性问题。我们不是试图做嵌套的exceptiosn并且总是清理事务,但我开始认为可能正在分享会话。
应用程序是多线程的,我开始怀疑getCurrentSession
实际上是跨线程的。我的印象是,通过将hibernate.current_session_context_class
设置为线程,然后getCurrentSession()将为每个线程提供单独的会话。我应该采取不同的方法吗?我应该使用openSession()
,还是以某种方式配置hibernate为每个线程提供唯一的会话?
我们使用@JmsListener
方法,而事务异常在那里似乎最为普遍,但未在那里进行本地化。
确切的hibernate版本如下:
hibernate: [ 'org.hibernate.common:hibernate-commons-annotations:4.0.4.Final',
'org.hibernate:hibernate-core:4.3.11.Final',
'org.hibernate:hibernate-hikaricp:4.3.11.Final'],
hikari: 'com.zaxxer:HikariCP:2.4.1',