hibernate保存并使用相同的会话,相同的事务

时间:2011-09-21 08:07:39

标签: java hibernate spring transactions

我有一个场景服务层是事务性的,我只能在完成trandaction之后提交。我把它简化成如下所示。

begin transaction

for(loop){

getHibernateTemplate().save(object);


getHibernateTemplate().get(object_by_key); //cannot get object by object_by_key because "object" is not commit into database until entire for(loop) completed. 

}

end transaction. commit();

我尝试在save()之后放入getHibernateTemplate()。flush()并且能够在show_sql中看到“insert”。但记录未显示在数据库内部。如何在每次save()之后强制写入数据库,而不是像上面那样等待提交?

4 个答案:

答案 0 :(得分:5)

getHibernateTemplate()。flush()是强制hibernate写入数据库的方法(发送插入和更新查询)。这是在事务中完成的,因此在事务提交之前,其他事务(从SQL客户端查询)不可见。

如果插入查询显示在日志中,则它已被发送到数据库。如果你想测试记录是否正确插入 - 你可以做一个getHibernateTemplate()。clear()(它将删除所有缓存的数据),然后做一个getHibernateTemplate.get()(它将从dataSource查询) 。或者另一种测试方法是使用jdbcTemplate(使用相同的数据库)进行查询和检查。

如果您使用的SQL客户端工具允许您指定隔离级别 - 单独启动SQL客户端会话read_uncommited - 将允许您在提交事务之前查看已完成的更改。

答案 1 :(得分:0)

getHibernateTemplate()每次都返回相同的模板吗?或者如果不是基于公共会话的模板。最好将模板保存到局部变量并重用它,而不是每次调用getHibernateTemplate()。

begin transaction

template = getHibernateTemplate();

for(loop){

template.save(object);


template.get(object_by_key); //cannot get object by object_by_key because "object" is not commit into database until entire for(loop) completed. 

}

end transaction. commit();

我认为您的问题可能是因为您使用不同的会话进行保存和接听电话。如果他们进入同一个会话,你应该看到你想要的行为。

答案 2 :(得分:0)

据我所知,你完全不能这样做。它不起作用。无法在同一事务中检索已保存的对象。我认为这是因为会话是第一级缓存,只有在创建该对象的另一个事务提交时,Hibernate才能获取新对象。

答案 3 :(得分:0)

为什么需要按键获取对象?你已经拥有了这个对象! 如果你确实需要对象键(用于打印它?),你可以为每个保存操作使用一个新事务,将transaction begincommit放在循环中。