我已经阅读了entities lifecycle和the locking strategies,我看了一些关于此的视频,但我还是不确定我理解。我知道还有一个锁定机制在底层的RDBMS中(我使用mysql)。
我想知道在什么时候提交事务/实体是分离的,从锁定的角度来看它如何影响其他事务。在什么时候用户必须等到交易完成?我在下面做了两个不同的场景。为了便于理解,我在场景中断言表包含大量行,for
循环需要10分钟才能完成。
情景1:
@Stateless
public class AService implements AServiceInterface {
@PersistenceContext(unitName = "my-pu")
private EntityManager em;
@Override
public List<Aclass> getAll() {
Query query = em.createQuery(SELECT_ALL_ROWS);
return query.getResultList();
}
public void update(Aclass a) {
em.merge(a);
}
}
和一个调用类:
public aRadomClass{
@EJB
AServiceInterface service;
public void method(){
List<Aclass> listAclass = service.getAll();
for(Aclass a : listAclass){
a.setProperty(methodThatTakesTime());
service.update(a);
}
}
}
如果没有指定锁定策略:如果另一个用户想要更新表中的一个行,并且for循环已经开始但尚未完成。他必须等到for
循环完成吗?
情景2:
@Stateless
public class AService implements AServiceInterface {
@PersistenceContext(unitName = "my-pu")
private EntityManager em;
@Override
public List<Aclass> getAllAndUpdate() {
Query query = em.createQuery(SELECT_ALL_ROWS);
List<Aclass> listAclass = query.getResultList();
for(Aclass a : listAclass ){
a.setProperty(methodThatTakesTime());
em.merge(a);
}
}
}
同样的问题。
答案 0 :(得分:1)
重要的是你的aRandomClass是什么类。如果它也是EJB,您应该查看transaction propagation。如果它是一个servlet,那么在EJB方法退出后立即自动关闭事务(无论哪一个)。这是使用dynamic proxies完成的。因此,在方案1中,EJB容器将打开和关闭多个事务:一个用于service.getAll()
,一个用于每个service.update(a)
调用。在方案2中,如果方法getAllAndUpdate()
仅被调用一次,则将打开一个事务,并在方法退出时关闭它。