Hibernate没有显式Transaction

时间:2014-07-04 04:18:51

标签: java hibernate java-ee jdbc transactions

我试图理解在从Hibernate Documentation检索的以下代码中使用事务的原因。

Session session1 = factory1.openSession();
Transaction tx1 = session1.beginTransaction();
Cat cat = session1.get(Cat.class, catId);
tx1.commit();
session1.close();
//reconcile with a second database
Session session2 = factory2.openSession();
Transaction tx2 = session2.beginTransaction();
session2.replicate(cat, ReplicationMode.LATEST_VERSION);
tx2.commit();
session2.close();

我对此JBOSS Wiki 的理解是,即使我不使用在这种情况下不应该成为问题的交易。在隔离等方面,有些机构可以对此进行更多的教育。如果我们在上述场景中使用或不使用交易,实际会发生什么

与Hibernate非交易地工作 查看以下代码,该代码访问没有事务边界的数据库:

Session session = sessionFactory.openSession();   
session.get(Item.class, 123l);   
session.close();   

默认情况下,在具有JDBC配置的Java SE环境中,如果您执行此代码段会发生这种情况: 1.新会议开幕。此时它不会获得数据库连接。 2.对get()的调用会触发SQL SELECT。 Session现在从连接池获取JDBC连接。默认情况下,Hibernate会立即使用setAutoCommit(false)关闭此连接上的自动提交模式。这有效地启动了JDBC事务! 3. SELECT在此JDBC事务中执行。会话关闭,连接返回到池并由Hibernate释放 - Hibernate在JDBC Connection上调用close()。未提交的交易会发生什么?这个问题的答案是,“它取决于!”在连接上调用close()时,JDBC规范没有说明挂起事务的任何内容。发生的情况取决于供应商如何实施规范。例如,使用Oracle JDBC驱动程序,对close()的调用将提交事务!当JDBC Connection对象关闭并且资源返回到池时,大多数其他JDBC供应商采用理智的路由并回滚任何挂起的事务。显然,对于您执行的SELECT,这不会是一个问题,但请看这个变体:

1 个答案:

答案 0 :(得分:0)

如果它的一个声明你不会说出差异,但如果你想在 多个声明 < / strong>交易你会看到它们的用途。

如果您打开一个事务并尝试多个CRUD操作并且一个操作失败,您可以回滚事务并且几乎回到事务中的先前状态(甚至在所有事情之前)。

另一方面,如果你不打开一个事务,每次你使用一个语句就会隐式打开和关闭它,这样如果你做了多个CRUD操作而一个操作失败,就没有办法回滚数据你最终会得到糟糕的数据。

旁注:这对 选择 语句无关紧要