以下是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在此处设置为手动,因此无论如何操作(假设我们忽略此处的插入)都将命中数据库。那么为什么要在这里进行交易?
感谢
答案 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缓存将为您带来相同的对象副本,并允许您随意使用它们。