在Hibernate中手动设置flushmode时,transaction.commit()会做什么?

时间:2010-04-15 21:43:16

标签: hibernate orm

以下是Christian和Gavin撰写的Java Persistence with Hibernate一书中的代码块,

    
Session session = getSessionFactory().openSession();
session.setFlushMode(FlushMode.MANUAL);
// First step in the conversation
session.beginTransaction();
Item item = (Item) session.get(Item.class, new Long(123) );
session.getTransaction().commit();
// Second step in the conversation
session.beginTransaction();
Item newItem = new Item();
Long newId = (Long) session.save(newItem); // Triggers INSERT!
session.getTransaction().commit();
// Roll back the conversation!
session.close();//enter code here

我很困惑为什么第一步和第二步需要包含在两个单独的交易中?由于flushmode在此处设置为手动,因此无论如何操作(假设我们忽略此处的插入)都将命中数据库。那么为什么要在这里进行交易?

感谢

3 个答案:

答案 0 :(得分:1)

使用hibernate时,您必须始终拥有正在运行的事务。

以下是文档对MANUAL所说的内容:

  

此模式对于只读事务非常有效。

至于对话 - 它们应该跨越多种方法(read here)。所以我不认为你的例子应该是一种方法。

正如我所链接的文章所述,交易应该是“工作单位”。如果您认为有必要,请使用新的交易。但要确保它是必要的。否则 - 不要在一个请求中进行多个事务。

答案 1 :(得分:0)

我认为这是因为持久性最佳实践原因。 例如

Long newId = (Long) session.save(newItem);

在提交事务之前,项newItem将不会持久保存到数据库中。当“获得”

的实例时
Item item = (Item) session.get(Item.class, new Long(123) );

事务已提交,因为get()将检索持久对象。通过提交事务item将与事务分离,并且不会被持久化(直到明确更新并再次保存)。

关于wiki的更多信息

http://en.wikipedia.org/wiki/Object_database

http://en.wikipedia.org/wiki/Persistence_%28computer_science%29

答案 2 :(得分:0)

正如@Bozho所说,这对于只读事务非常有用。这些 非常有用。它们允许您同时使用相同版本的对象以实现两个不同的目的,而不会损害实际数据。在这种情况下,Hibernate缓存将为您带来相同的对象副本,并允许您随意使用它们。