我有一个场景服务层是事务性的,我只能在完成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()之后强制写入数据库,而不是像上面那样等待提交?
答案 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 begin
和commit
放在循环中。