简体   繁体   English

Hibernate获取而无需显式事务

[英]Hibernate get without explicit Transaction

I am trying to understand the reason behind using transaction in the following piece of code retrieved from Hibernate Documentation. 我试图理解从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();

What I understand from this JBOSS Wiki that even though if I dont use a transaction that should not be a problem in this case. 从这个JBOSS Wiki上我了解到,即使我不使用事务处理,在这种情况下也不应该成为问题。 Can some body educate me more on this in terms of isolation etc . 有人能在隔离等方面对我进行更多的教育。 what actually happens if we do or dont use transaction in the above scenario 在上述情况下我们使用或不使用交易时实际发生的情况

Working nontransactionally with Hibernate Look at the following code, which accesses the database without transaction boundaries: 与Hibernate进行非事务处理请看以下代码,该代码无事务限制地访问数据库:

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

By default, in a Java SE environment with a JDBC configuration, this is what happens if you execute this snippet: 1. A new Session is opened. 默认情况下,在具有JDBC配置的Java SE环境中,如果执行以下代码片段,将发生以下情况:1.打开一个新的Session。 It doesn't obtain a database connection at this point. 此时,它尚未获得数据库连接。 2. The call to get() triggers an SQL SELECT. 2.调用get()会触发一个SQL SELECT。 The Session now obtains a JDBC Connection from the connection pool. 现在,会话从连接池获取JDBC连接。 Hibernate, by default, immediately turns off the autocommit mode on this connection with setAutoCommit(false). 默认情况下,Hibernate使用setAutoCommit(false)立即关闭此连接上的自动提交模式。 This effectively starts a JDBC transaction! 这有效地启动了JDBC事务! 3. The SELECT is executed inside this JDBC transaction. 3. SELECT在此JDBC事务内执行。 The Session is closed, and the connection is returned to the pool and released by Hibernate — Hibernate calls close() on the JDBC Connection. Session关闭,并且连接返回到池中并由Hibernate释放-Hibernate在JDBC Connection上调用close()。 What happens to the uncommitted transaction? 未提交的交易会怎样? The answer to that question is, “It depends!” The JDBC specification doesn't say anything about pending transactions when close() is called on a connection. 该问题的答案是:“取决于!”当在连接上调用close()时,JDBC规范未提及任何有关挂起事务的信息。 What happens depends on how the vendors implement the specification. 发生什么情况取决于供应商如何实施规范。 With Oracle JDBC drivers, for example, the call to close() commits the transaction! 例如,使用Oracle JDBC驱动程序,对close()的调用将提交事务! Most other JDBC vendors take the sane route and roll back any pending transaction when the JDBC Connection object is closed and the resource is returned to the pool. 当JDBC Connection对象关闭并且资源返回到池中时,大多数其他的JDBC供应商都会采用合理的路由并回滚任何未决的事务。 Obviously, this won't be a problem for the SELECT you've executed, but look at this variation: 显然,这对于您执行的SELECT来说不是问题,但请看以下变化:

If its one statement you wouldnt tell the difference, but if you are trying to do multiple statements in a single transaction you would see what they are for. 如果只说一条语句,您不会说出其中的区别,但是如果您尝试在单个事务中执行多条语句 ,则会看到它们的用途。

If you open a transaction and attempt multiple CRUD operations and one fails, you can roll back the transaction and pretty much go back to a previous state within the transaction (even before everything). 如果您打开一个事务并尝试执行多个CRUD操作而一次失败,则可以回滚该事务,并且几乎可以返回到事务中的先前状态(甚至在所有操作之前)。

On the other hand, if you dont open a transaction, its opened and closed implicitly every time you use a statement so if you do multiple CRUD operations and one fails, there is no way to roll back the data and you will end up with bad data. 另一方面,如果您不打开事务,则每次使用一条语句时都会隐式打开和关闭事务,因此,如果您执行多个CRUD操作而失败,则无法回滚数据,结果会很糟糕数据。

Side note : this doesnt really matter for select statements 旁注:这对于选择语句并不重要

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM