打开新的EntityManager后的线程锁定 [英] Thread lock after opening new EntityManager

查看:368
本文介绍了打开新的EntityManager后的线程锁定的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在处理Spring JPA事务时,我遇到一个非常奇怪的错误.线程被锁定约16分钟,然后继续进行,没有任何问题.

I have a very weird error working with Spring JPA transactions. The thread is locked around 16 minutes and then continues without any problem.

这里是情况:

@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日志,这就是我看到的:

Taking a look to the log file I see that it takes 16 minutes from log "calling encrypt method" to "encripting". So, have activated JTA logs and this is what I see:

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中运行应用程序.

我知道,使用此信息很难找出问题出在哪里.我只是希望有人能提供一些想法,以帮助我发现正在发生的事情.

I know that with this information is difficult to find out where the problem is. Just I hope someone can contribute with some thoughts that help me to find what is happening.

推荐答案

对我来说,这听起来很像

For me this sounds pretty much like this SO question.

使用REQUIRES_NEW将始终确保新的交易,因此,如果已经存在一个应暂停的交易.

Using REQUIRES_NEW will always ensure a new Transaction, so if there is an already existing one that should be suspended.

但由于 JPATransactionManager :

在JDBC 3.0上,此事务管理器通过以下方式支持嵌套事务: JDBC 3.0保存点.这 AbstractPlatformTransactionManager.setNestedTransactionAllowed(boolean) 不过,"nestedTransactionAllowed"}标志默认为"false",因为 嵌套事务将仅适用于JDBC连接,而不适用于 JPA EntityManager及其缓存的对象.您可以手动设置 如果要使用嵌套事务进行JDBC访问,请标记为"true" 参与JPA交易的代码(前提是您的JDBC 驱动程序支持保存点).请注意,JPA本身不支持 嵌套交易!因此,不要期望JPA访问代码能够 在语义上参与嵌套事务.

On JDBC 3.0, this transaction manager supports nested transactions via JDBC 3.0 Savepoints. The AbstractPlatformTransactionManager.setNestedTransactionAllowed(boolean) "nestedTransactionAllowed"} flag defaults to "false", though, as nested transactions will just apply to the JDBC Connection, not to the JPA EntityManager and its cached objects. You can manually set the flag to "true" if you want to use nested transactions for JDBC access code which participates in JPA transactions (provided that your JDBC driver supports Savepoints). Note that JPA itself does not support nested transactions! Hence, do not expect JPA access code to semantically participate in a nested transaction.

因此,这两个事务将共享相同的JDBC连接,并且可能涉及一些锁定.是不是将事务超时设置为15分钟,这就是为什么您会看到它徘徊了这么长的时间?

So the two transactions will share the same JDBC connection and there might be some locking involved. Is it that the transaction timeout is set to 15 minutes and that's why you see it hanging around for this amount of time?

这篇关于打开新的EntityManager后的线程锁定的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆