Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/spring/13.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/jsp/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 打开新EntityManager后的线程锁定_Java_Spring_Hibernate_Jpa_Transactions - Fatal编程技术网

Java 打开新EntityManager后的线程锁定

Java 打开新EntityManager后的线程锁定,java,spring,hibernate,jpa,transactions,Java,Spring,Hibernate,Jpa,Transactions,我在处理Spring JPA事务时遇到了一个非常奇怪的错误。线程锁定大约16分钟,然后继续运行,没有任何问题 情况如下: @Transactional(propagation = Propagation.REQUIRES_NEW) public class A { public String encrypt(String str){ LOG.debug("encrypting..."); // just data base read operatio

我在处理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");

        ...
    }
}
查看日志文件,我发现从日志“调用加密方法”到“加密”需要16分钟。所以,我激活了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
...
以下是事实:

  • 错误并不总是发生,但当它发生时,它总是在同一点上
  • 大约16分钟后,线程继续并多次调用相同的方法,没有问题,并正确完成
  • 当它发生时,总是在15分30秒左右
  • 它在没有并发的情况下发生。无论如何,当一个线程被锁定时,如果我启动另一个线程就没有问题了。第二个线程在第一个线程仍处于锁定状态时进行处理
  • 正在检查DDBB,以查找发生锁定时的数据库锁定。未找到数据库锁
  • 从代码的其他点调用类A中的其他方法并没有问题
  • 只发生在生产环境中。你可以想象做改变有多困难
  • 数据库连接通过JNDI连接到MySql,应用程序在Tomcat中运行

我知道用这些信息很难找出问题所在。只是我希望有人能提供一些想法,帮助我找到正在发生的事情。

对我来说,这听起来很像

使用REQUIRES_NEW将始终确保有一个新的事务,因此如果已经存在一个事务,则应暂停该事务

但由于嵌套事务不受

在JDBC3.0上,此事务管理器支持通过 JDBC3.0保存点。这个 AbstractPlatformTransactionManager.setNestedTransactionAllowed(布尔值) “nestedTransactionAllowed”}标志默认为“false”,但如下所示 嵌套事务将只应用于JDBC连接,而不应用于 JPA EntityManager及其缓存对象。您可以手动设置 如果要使用嵌套事务进行JDBC访问,请将标志设置为“true” 参与JPA事务的代码(前提是您的JDBC 驱动程序支持保存点)。请注意,JPA本身不支持 嵌套事务!因此,不要期望JPA访问代码 语义上参与嵌套事务


因此,这两个事务将共享同一个JDBC连接,并且可能会涉及一些锁定。事务超时是否设置为15分钟,这就是为什么您看到它在这段时间内挂起的原因?

感谢您的贡献。没有定义事务超时,因此我们使用默认值(-1)。而且,我认为这无法解释为什么它不总是发生。我必须找出16个是从哪里来的,我认为这是关键。如果你需要新的,它会复制吗?我没有测试它。我们在PCI-DSS生产环境中工作,因此进行更改非常复杂。我所做的是在类级别删除事务,并在所需的方法中定义它。由于“encrypt”方法不需要事务,我们希望不会再次遇到错误。让我看看。我将尝试在其他环境中重现错误(如果幸运的话),并测试您的想法。问题出在防火墙上。在连接配置中做一些更改就解决了这个问题。介意分享一下必要的配置更改是什么吗?你应该把它作为一个真实的答案贴出来