2015-08-05 4 views
1

Я читал о 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

Подробнее о [управлении параллелизмом] (https://en.wikipedia.org/wiki/Concurrency_control). – philipxy

ответ

1

Важно, какой класс является вашим классом aRandomClass. Если это также EJB, вы должны взглянуть на transaction propagation. Если это сервлет, транзакция автоматически закрывается сразу после выхода вашего метода EJB (независимо от того, какой из них). Это делается с использованием dynamic proxies. Таким образом, в сценарии 1 контейнер EJB откроет и закроет несколько транзакций: один для service.getAll() и по одному для каждого звонка service.update(a). В сценарии 2, если метод getAllAndUpdate() вызывается только один раз, одна транзакция будет открыта и будет закрыта при выходе метода.

+0

@AndreiL Вы говорите, что это важно, если это EJB, а не в случае с управляемым правым правым? Итак, в сценарии 1, если цикл for продолжается, и кто-то делает обновление для строки, возможно ли, что обновление выполняется во время цикла, но в сценарии 2 он должен ждать? Как я представляю, цикл for начинается, совершает транзакцию, закрывает ее, а затем, прежде чем открывать другую транзакцию для завершения цикла, выполняется транзакция обновления от другого пользователя, тогда цикл продолжается? – Ced

+0

Об управляемых компонентах Я не уверен, но это очень легко проверить: [включить все запросы, выполняемые MySql] (https://dev.mysql.com/doc/refman/5.1/en/query-log.html) а затем начните отладку приложения и проверьте, на каком этапе выполняется. –

+0

На ваш комментарий у меня нет ответа. Если вы находитесь в этом цикле в сценарии 1, каждый раз, когда вы закончите с циклом, транзакция закрывается, и любые закрытые блокировки БД будут потеряны при закрытии транзакции (но в вашем коде у вас все равно не будут блокировки, за исключением того, что вы используете сериализуемый [режим изоляции транзакции] (https://en.wikipedia.org/wiki/Isolation_%28database_systems%29)). –

Смежные вопросы