如何正确处理并发?

时间:2017-08-27 00:30:13

标签: java jpa concurrency ejb

我正在使用javaEE构建REST API。我正在使用TomEE作为应用程序服务器。我有一个Stateless JPA DAO来处理Postgres数据库和GET服务,以便为我的RESTfull类提供方法,该类具有POSTDELETE Runnable r1 = () -> { for (int i = 0; i < 10; i++) { RegisterAndLogService service = new RegisterAndLogService(); //lots of service calls } }; Runnable r2 = () -> { for (int i = 0; i < 10; i++) { RegisterAndLogService service2 = new RegisterAndLogService(); //lots of service calls } }; Thread t1 = new Thread(r1); Thread t2 = new Thread(r2); t1.start(); t2.start(); 方法。到现在为止,我正在使用rest assured来测试我的网址路由。一切都很好,但我想强调我的系统,所以我这样做了:

java.lang.IllegalStateException: Transaction already active

但是当我的一个线程上的第二次迭代开始时,我得到了这个:

{{1}}

我如何能够一次一个地堆积dao请求并正确处理它们,等待当前的事务完成? EJB / JPA可以以某种方式参与其中吗?进入保存请求请求并尽快处理它们?

1 个答案:

答案 0 :(得分:1)

很难理解你在这里做了什么,以及你所问的问题是在测试代码中还是在测试中的API中......或者API背后的东西。

但是如果你得到一个&#34;交易已经活跃&#34;这意味着某事正在做类似的事情:

  • 尝试使用具有多个线程的单个JPA事务管理器(不要)
  • 尝试在同一个帖子上进行多个同步交易(不要)或
  • 不清理(提交或回滚)交易。

在最后一种情况下,寻找可以逃避的案例。来自负责交易的代码区域,通过异常将其回滚。

我建议您查看一直使用的JPA文档,以确保您了解事务,事务管理器和线程之间的关系。

  

我相信我的情况是第一个 - 尝试使用具有多个线程的单个JPA事务管理器。是否有任何关于保留单个JPA事务管理器的设计模式或良好实践,同时请求大量无状态bean实例?

唯一有效的方法是每个线程都有自己的事务管理器。每个线程都必须以编程方式创建(并释放)自己的TM,或者依靠框架来执行此操作;例如按照各种注释的指示。

TM对象被设计为轻量级(即,实例化便宜)和非线程安全的。你不应该通过主题 1 分享它们,你不应该回收它们。

1 - ...除非您有一个需要来跨越多个线程的JPA事务。为此,有#34;方法可以做到这一点&#34;。