我在使用Spring JPA事务时遇到了一个非常奇怪的错误。线程被锁定大约16分钟,然后继续没有任何问题。
情况如下:
@Transactional(propagation = Propagation.REQUIRES_NEW)
public class A {
public String encrypt(String str){
LOG.debug("encrypting...");
// just data base read operations
}
public String encrypt(String str, String str2){
// read and write database operations.
}
public String foo(...){
// read and write database operations.
}
public String bar(...){
// read and write database operations.
}
}
@Transactional(propagation = Propagation.REQUIRES_NEW)
public class B {
public String doSomething(...){
LOG.debug("calling encrypt method...");
String chain1 = this.a.encrypt("whatever");
LOG.debug("calling encrypt method...");
String chain2 = this.a.encrypt("again");
LOG.debug("calling encrypt method...");
String chain3 = this.a.encrypt("and again");
...
}
}
看一下日志文件,我发现从log"调用加密方法"需要16分钟。 to" encripting"。所以,已经激活了JTA日志,这就是我所看到的:
15:09:04.317 DEBUG e.i.n.p.d.TipoMensajeDaoDelegate [45] - obteniendo mensaje para tipo operacion 0104 y protocolo 03
15:09:04.318 DEBUG o.s.orm.jpa.JpaTransactionManager [332] - Found thread-bound EntityManager [org.hibernate.ejb.EntityManagerImpl@4e6b01e9] for JPA transaction
15:09:04.319 DEBUG o.s.orm.jpa.JpaTransactionManager [471] - Participating in existing transaction
15:09:04.320 DEBUG o.s.orm.jpa.JpaTransactionManager [332] - Found thread-bound EntityManager [org.hibernate.ejb.EntityManagerImpl@4e6b01e9] for JPA transaction
15:09:04.321 DEBUG o.s.orm.jpa.JpaTransactionManager [471] - Participating in existing transaction
15:09:04.324 DEBUG e.i.n.c.p.p.b.B [485] - calling encrypt method...
15:09:04.325 DEBUG o.s.orm.jpa.JpaTransactionManager [332] - Found thread-bound EntityManager [org.hibernate.ejb.EntityManagerImpl@4e6b01e9] for JPA transaction
15:09:04.326 DEBUG o.s.orm.jpa.JpaTransactionManager [416] - Suspending current transaction, creating new transaction with name [es.indra.nnp.gestorclaves.GestorClavesServiceImpl.cifrar]
15:09:04.326 DEBUG o.s.orm.jpa.JpaTransactionManager [369] - Opened new EntityManager [org.hibernate.ejb.EntityManagerImpl@27f2b012] for JPA transaction
...
15:24:29.954 DEBUG o.s.orm.jpa.JpaTransactionManager [408] - Not exposing JPA transaction [org.hibernate.ejb.EntityManagerImpl@27f2b012] as JDBC transaction because JpaDialect [org.springframework.orm.jpa.DefaultJpaDialect@4d832b01] does not support JDBC Connection retrieval
15:24:29.955 DEBUG e.i.n.g.A [146] - encrypting
15:24:29.956 DEBUG o.s.orm.jpa.JpaTransactionManager [332] - Found thread-bound EntityManager [org.hibernate.ejb.EntityManagerImpl@27f2b012] for JPA transaction
15:24:29.957 DEBUG o.s.orm.jpa.JpaTransactionManager [471] - Participating in existing transaction
15:24:29.958 DEBUG o.s.orm.jpa.JpaTransactionManager [332] - Found thread-bound EntityManager [org.hibernate.ejb.EntityManagerImpl@27f2b012] for JPA transaction
15:24:29.958 DEBUG o.s.orm.jpa.JpaTransactionManager [471] - Participating in existing transaction
15:24:29.962 DEBUG o.s.orm.jpa.JpaTransactionManager [332] - Found thread-bound EntityManager [org.hibernate.ejb.EntityManagerImpl@27f2b012] for JPA transaction
15:24:29.962 DEBUG o.s.orm.jpa.JpaTransactionManager [471] - Participating in existing transaction
...
这里,事实:
我知道有了这些信息很难找出问题所在。我希望有人可以提供一些帮助我找到正在发生的事情的想法。
答案 0 :(得分:1)
对我而言,这听起来非常像this SO question。
使用REQUIRES_NEW将始终确保新的交易,因此如果已存在应该暂停的交易。
但由于JPATransactionManager不支持嵌套交易:
在JDBC 3.0上,此事务管理器支持嵌套事务 JDBC 3.0保存点。该 AbstractPlatformTransactionManager.setNestedTransactionAllowed(布尔) 但是,“nestedTransactionAllowed”}标志默认为“false” 嵌套事务只适用于JDBC连接,而不适用于 JPA EntityManager及其缓存对象。你可以手动设置 如果要使用嵌套事务进行JDBC访问,则标记为“true” 参与JPA事务的代码(假设您的JDBC 驱动程序支持保存点)。请注意,JPA本身不支持 嵌套交易!因此,不要指望JPA访问代码 语义上参与嵌套事务。
因此,这两个事务将共享相同的JDBC连接,并且可能涉及一些锁定。交易超时是否设置为15分钟,这就是为什么你看到它停留了这么长时间?