【发布时间】:2013-10-07 11:03:49
【问题描述】:
我有一个 Singleton-EJB,它从具有特定状态的数据库中读取所有对象。然后我对这些对象做一些事情并将状态设置为其他:
@Singleton
public class MyEJB {
@PersistenceContext(unitName = "MyPu")
private EntityManager em;
@Lock(LockType.WRITE)
public void doSomeStuffAndClose() {
List<MyObj> objects = getAllOpenObjects();
for (MyObj obj : objects) {
// do some stuff here...
obj.setClosed(true);
}
}
private List<MyObj> getAllOpenObjects() {
TypedQuery<MyObj> q = em.createQuery("select o from MyObj o "
+ "where o.closed = false", MyObj.class);
return q.getResultList();
}
}
现在,如果我想确保我的方法不能被同时调用,我添加注解@Lock(LockType.WRITE)。但是在数据库中设置状态的事务是在锁被释放后提交的,下一个调用者可能会再次抓取相同的对象。
我怎样才能防止这种情况发生?
【问题讨论】:
-
了解事务隔离级别。
-
为什么不让
doSomeStuffAndClose同步? -
@frostjogla 感谢您的评论,这很有趣。所以解决方案是将隔离级别设置为“可序列化”。但这不是我的选择,我的 bean 使用共享连接。
-
@siledh 在 java EE 中的容器你不能使用同步关键字
-
@Chechus 因为这会被认为是不好的做法,还是有任何形式上的限制?我不明白为什么同步在这里不起作用,它会实现 OP 想要的一切。
标签: java jakarta-ee concurrency transactions singleton