【发布时间】:2014-08-25 08:10:51
【问题描述】:
我试图了解在从 Hibernate 文档检索到的以下代码中使用事务背后的原因。
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 环境中,如果执行这个 sn -p 会发生以下情况: 1. 一个新的会话被打开。此时它没有获得数据库连接。 2. 调用 get() 触发 SQL SELECT。 Session 现在从连接池中获得一个 JDBC Connection。默认情况下,Hibernate 会立即使用 setAutoCommit(false) 关闭此连接上的自动提交模式。这有效地启动了一个 JDBC 事务! 3. SELECT 在这个 JDBC 事务中执行。会话关闭,连接返回池并由 Hibernate 释放——Hibernate 调用 JDBC Connection 上的 close()。未提交的事务会发生什么?这个问题的答案是,“这取决于!”当在连接上调用 close() 时,JDBC 规范没有说明待处理的事务。会发生什么取决于供应商如何实施规范。例如,对于 Oracle JDBC 驱动程序,对 close() 的调用会提交事务!大多数其他 JDBC 供应商采用理智的方式,并在 JDBC Connection 对象关闭并将资源返回到池时回滚任何待处理的事务。显然,这对于您执行的 SELECT 来说不会有问题,但是看看这个变体:
【问题讨论】:
标签: java hibernate jakarta-ee jdbc transactions