为什么我在Hibernate中需要Transaction才能进行只读操作? [英] Why do I need Transaction in Hibernate for read-only operations?

查看:166
本文介绍了为什么我在Hibernate中需要Transaction才能进行只读操作?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

为什么我在Hibernate中需要Transaction才能进行只读操作?

Why do I need Transaction in Hibernate for read-only operations?

以下事务是否会锁定数据库?

Does the following transaction put a lock in the DB?

从DB获取的示例代码:

Example code to fetch from DB:

Transaction tx = HibernateUtil.getCurrentSession().beginTransaction(); // why begin transaction?
//readonly operation here

tx.commit() // why tx.commit? I don't want to write anything

我可以使用 session.close( )而不是 tx.commit()

推荐答案

您可能实际上有理由将交易标记为只读。

You might actually have reasons to mark transactions as read-only.


  1. 阅读交易可能看起来确实很奇怪在这种情况下,不要标记交易方法。但是JDBC无论如何都会创建事务,如果没有明确设置不同的选项,它只会在 autocommit = true 中工作。

  2. 但是无法保证您的方法不会写入数据库。如果将方法标记为 @Transactional(readonly = true),Spring会将JDBC事务设置为只读模式,因此您将指示它是否实际上是 可以在此事务的范围内写入DB。如果您的体系结构非常繁琐且某些团队成员可能没有遵循合理的路径,那么这个标志会指向您有问题的地方。

  3. 此外,只读事务可以由DB优化,但是这样当然是DB特定的。例如。 MySQL仅在InnoDB中添加了对5.6.4版本的支持。

  4. 如果您不直接使用JDBC,而是使用ORM,则可能会出现问题。例如,Hibernate社区表示在事务之外工作可能会导致不可预测的行为。这是因为Hibernate将打开事务,但它不会自己关闭它,因此连接将返回到连接池,而事务未被提交。那么会发生什么? JDBC保持沉默,因此这是特定于实现的(MySQL回滚事务,Oracle afair提交它)。这也可以在连接池级别配置(例如C3P0为您提供了这样一个选项,默认情况下回滚)。

  5. 另一方面,对于Hibernate,Spring将FlushMode设置为MANUAL以防万一只读事务,这会导致其他优化,例如不需要进行脏检查。

  6. 您可能希望显式覆盖或设置事务隔离级别。这也影响了读取事务,因为您确实或不想读取未提交的更改,暴露于幻像读取等。

  1. Transactions for reading might look indeed strange and often people don't mark methods for transactions in this case. But JDBC will create transaction anyway, it's just it will be working in autocommit=true if different option wasn't set explicitly.
  2. But there is no guarantee that your method doesn't write into the database. If you mark method as @Transactional(readonly=true), Spring will set the JDBC transaction into a read-only mode, thus you'll dictate whether it's actually possible to write into DB in scope of this transaction. If you architecture is pretty cumbersome and some team members might not follow reasonable path, this flag would point you to the problematic place.
  3. Also read-only transactions can be optimized by DBs, but this of course is DB specific. E.g. MySQL added support for this only in InnoDB starting from 5.6.4 version.
  4. If you're not using JDBC directly, but rather an ORM, that might be problematic. For instance Hibernate community says that working outside of transaction might cause unpredictable behavior. This is because Hibernate will open transaction, but it won't close it on its own, thus connection will be returned to the Connection Pool with transaction being not committed. What happens then? JDBC keeps silence, thus this is implementation specific (MySQL rolls back transaction, Oracle afair commits it). This also can be configured on Connection Pool level (e.g. C3P0 gives you such an option, rollback by default).
  5. Another thing when it comes to Hibernate, Spring sets the FlushMode to MANUAL in case of read-only transactions, which leads to other optimizations like no need for dirty checks.
  6. You may want to override or set explicitly the transaction isolation level. This impacts read-transactions as well since you do or don't want to read uncommitted changes, be exposed to phantom reads, etc.

总结一下 - 你可以双向进行,但你需要了解后果。

To sum up - you can go both ways, but you need to understand consequences.

这篇关于为什么我在Hibernate中需要Transaction才能进行只读操作?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆