我有一个Singleton-EJB,它从数据库中读取具有特定状态的所有对象.然后,我对这些对象进行处理,并将状态设置为其他状态:
@Singleton
public class MyEJB {
@PersistenceContext(unitName = "MyPu")
private EntityManager em;
@Lock(LockType.WRITE)
public void doSomeStuffAndClose() {
List objects = getAllOpenObjects();
for (MyObj obj : objects) {
// do some stuff here...
obj.setClosed(true);
}
}
private List getAllOpenObjects() {
TypedQuery q = em.createQuery("select o from MyObj o "
+ "where o.closed = false", MyObj.class);
return q.getResultList();
}
}
现在,如果我想确保不能同时调用我的方法,请添加注释@Lock(LockType.WRITE).但是设置数据库状态的事务是在释放锁定后提交的,下一个调用方有可能再次获取相同的对象.
我该如何预防?
解决方法:
您可以使用SELECT FOR UPDATE序列化对行的访问.
q.setLockMode(LockModeType.PESSIMISTIC_WRITE)
标签:concurrency,transactions,singleton,java,java-ee
来源: https://codeday.me/bug/20191122/2061772.html