Параллельное выполнение нескольких JPA-транзакций - PullRequest
4 голосов
/ 11 мая 2011

У меня есть два (или более) потока Java, создающих, обновляющих и удаляющих объекты из базы данных mysql с использованием JPA. Для этого у меня есть класс PersistenceLayer, создающий EntityManager и обеспечивающий методы сохранения, обновления и удаления для всех моих сущностей, выглядящие следующим образом:

public void saveEntity(Entity entity) {
    manager.getTransaction().begin();
    manager.persist(entity);
    manager.getTransaction().commit();
}

public void saveEntity2(Entity2 entity) {
    manager.getTransaction().begin();
    manager.persist(entity);
    manager.getTransaction().commit();
}

Если один поток входит в операцию saveEntity, а другой - в saveEntity2 одновременно, оба будут пытаться получить транзакцию из EntityManager, которая не удастся выполнить. Однако я всегда думал, что базовая база данных способна управлять несколькими транзакциями, особенно если обе они работают в разных строках или даже в разных таблицах. Конечно, я мог синхронизировать блоки, но это означало бы, что одновременно возможно только одно соединение с БД, которое не будет масштабироваться для нескольких пользователей, создающих несколько потоков.

Какое неверное предположение я здесь делаю? Можно ли отправить несколько транзакций в базу данных через JPA и позволить БД обрабатывать проблемы параллелизма?

Ответы [ 2 ]

6 голосов
/ 11 мая 2011

EntityManager не предназначен для использования несколькими потоками. Вам необходимо получить отдельные экземпляры EntityManager для каждого потока.

На самом деле, если вы используете EJB или Spring, вы можете использовать область транзакции EntityManager, которая может использоваться из нескольких потоков (это прокси, который делегирует фактическую работу отдельным экземплярам с привязкой к потоку EntityManager), но Я думаю, что это не ваше дело.

2 голосов
/ 11 мая 2011

Для обработки проблем параллелизма, когда объект обрабатывается в нескольких транзакциях, можно получить блокировку для объекта.Блокировка Optimistic или Pessimistic может использоваться с соответствующими режимами блокировки.

Блокировка версионного объекта с помощью entityManager.lock(entity, LockModeType.READ) гарантирует, что он предотвратит любое Грязное чтение & Неповторяемое чтение .

LockModeType.WRITEпринудительно увеличивает / обновляет столбец версии объекта.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...