【发布时间】:2012-02-09 16:18:27
【问题描述】:
我正在为我的 Web 应用程序使用每个请求模型的休眠会话。我的 jdbc 事务从每个 Web 请求的开头开始,并在最后提交。
// 非托管环境成语
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 个打开的会话使用休眠加载同一个集合。
我是否应该将每个 DAO 调用包含在其自己的事务中,并使用 JTA 进行事务传播?有没有办法避免 JTA?是否可以在调用 MyEntityADAO.save() 之后提交与主会话关联的事务并在之后立即在主会话上调用 beginTransaction 并像现在一样在请求结束时提交事务?
【问题讨论】:
标签: java hibernate transactions synchronization jta