Я использую сеанс гибернации для каждой модели запроса для своего веб-приложения.Моя транзакция jdbc начинается в начале каждого веб-запроса и фиксируется в конце.
// Идиома неуправляемой среды
Session sess = factory.openSession();
Transaction tx = null;
try {
tx = sess.beginTransaction();
// do some work
...
tx.commit();
}
catch (RuntimeException e) {
if (tx != null) tx.rollback();
throw e; // or display error message
}
finally {
sess.close();
}
Я столкнулся с проблемой, когда тестируюдля существования сущности (A), основанной на нескольких параметрах и выполняющей вставку, только если она не существует.
public synchronized myMethod(param1, param2) {
MyEntityA entity = MyEntityADAO.findEntity(param1, param2)
if (entity == null) {
entity = .../create entity
MyEntityADAO.save(entity);
}
}
проблема заключается в том, что синхронизация не помогает, поскольку вызов MyEntityADAO.save ()фактически не записывает в базу данных, когда текущий запущенный поток выходит из метода и снимает блокировку, запись в базу данных происходит после фиксации транзакции, что, как правило, мне нужно для моего приложения, за исключением нескольких сценариев.Приведенный выше код приводит к тому, что несколько записей сохраняются с одними и теми же параметрами в многопоточной среде.
Я пытался выполнить код сохранения в своем новом сеансе и транзакции:
public synchronized myMethod(param1, param2) {
MyEntityA entity = MyEntityADAO.findEntity(param1, param2)
if (entity == null) {
entity = .../create entity
Session session = HibernateUtil.createSession();
MyEntityADAO.save(entity);
Transaction t = session.beginTransaction();
}
}
, приведенные выше причиныпроблемы с 2 открытыми сессиями, загружающими одну и ту же коллекцию с помощью hibernate в некоторых случаях.
Должен ли я заключать каждый вызов DAO в свою собственную транзакцию и использовать распространение транзакций с JTA?Есть ли способ избежать JTA?Можно ли зафиксировать транзакцию, связанную с основным сеансом, после вызова MyEntityADAO.save () и вызвать beginTransaction в основном сеансе сразу после завершения транзакции, а транзакция зафиксирована в конце запроса, как сейчас?