【问题标题】:Multiple Threads starting a Transaction within JUNIT在 JUNIT 中启动事务的多个线程
【发布时间】:2012-01-21 13:04:58
【问题描述】:

我正在尝试通过编写单元测试在我的一种方法中重现(而不是全面测试多线程问题)线程块问题。因为我看到很多

org.hibernate.exception.LockAcquisitionException: could not execute update query

在我们的 2 服务器 PROD 环境中,我应该能够在我的单元测试中相当容易地重现。 我试图在我的 JUnit 方法和调用我的方法的每个线程中生成多个线程。我一开始就尝试了 2 个线程。

ExecutorService exec = Executors.newFixedThreadPool(16);
    for (int i = 0; i < 2; i++) {
        exec.execute(new Runnable() {
             public void run() {
                 System.out.println("who is running: " + Thread.currentThread().getId());
                 em.getTransaction().begin();
                //do something()
                 em.getTransaction().commit();
             }
        });
    }

我收到一个错误:

Exception in thread "pool-1-thread-2" who is running: 11
java.lang.IllegalStateException: Transaction already active
at org.hibernate.ejb.TransactionImpl.begin(TransactionImpl.java:35)

它不允许我为第二个线程创建事务并出现错误“事务已处于活动状态”。我认为 EntityManager 可以在任何给定时间存在多个活动线程(因此是单例实体管理器)?

我错过了什么吗?

谢谢

【问题讨论】:

    标签: multithreading transactions junit entitymanager


    【解决方案1】:

    EntityManager 不是线程安全的。这就是为什么经常有人告诉你不应该将 EntityManager 注入到像 Servlet 这样的共享实例中。它被清楚地记录在案(JSR-317 第 286 页):

    一个实体管理器不能在多个并发之间共享 执行线程,因为实体管理器和持久性上下文是 不需要是线程安全的。只能访问实体管理器 以单线程方式。

    【讨论】:

    • 我尝试创建多个 EntityManager 并为每个线程关联它们,但在第一个线程创建活动 Tx 后我仍然遇到“线程已处于活动状态”。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-02-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-06-16
    相关资源
    最近更新 更多