我正在改变我的JPA代码以利用线程.我为每个线程都有一个单独的实体管理器和事务.
我曾经拥有(针对单线程环境)的代码如下:
// get object from the entity manager
X x = getObjectX(jpaQuery);
if(x == null)
{
x = new X();
x.setVariable(foo);
entityManager.persist(x);
}
Run Code Online (Sandbox Code Playgroud)
使用多线程环境中的代码我得到重复键,因为我认为,getObjectX为一个线程返回null,然后该线程被换出,下一个线程调用getObjextX,也变为null,然后两个线程将创建并持久化一个新的X().
如果没有同步添加,是否有一种原子方法来获取/保存 - 如果不存在JPA的值或者我应该重新考虑我的方法
编辑:
我正在使用最新的Eclipselink和MySql 5.1
编辑2:
我添加了同步... MASSIVE性能命中(到了无法使用的程度).要在主线程上收集所有数据,然后在该线程上进行创建.
简短而悲伤的答案是,JPA API 无法为您做到这一点。整个 API 或多或少是围绕乐观原则构建的,即假设一切正常,并在并发修改时抛出异常。
如果这种情况经常发生,那么可能有一些其他组件(无论什么生成 foo?)可以从线程安全中受益,这也许是围绕查询+创建进行同步的替代方案。