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

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

问题描述

为什么我需要 Hibernate 中的事务来进行只读操作?

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

以下事务是否在数据库中加锁?

Does the following transaction put a lock in the 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() 吗?

Can I use session.close() instead of tx.commit()?

推荐答案

您实际上可能有理由将事务标记为只读.

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

  1. 用于读取的事务可能看起来确实很奇怪,而且在这种情况下,人们通常不会标记事务的方法.但是 JDBC 无论如何都会创建事务,只是如果没有明确设置不同的选项,它将在 autocommit=true 中工作.
  2. 但不能保证您的方法不会写入数据库.如果您将方法标记为 @Transactional(readonly=true),Spring 会将 JDBC 事务设置为只读模式,因此您将决定它是否实际上可能在此事务范围内写入数据库.如果您的架构很繁琐,并且某些团队成员可能会选择将修改查询放在非预期的位置,则此标志会将您指向有问题的地方.
  3. 也可以通过数据库优化只读事务,但这当然是数据库特定的.例如.MySQL 从 5.6.4 版本开始仅在 InnoDB 中添加了对此的支持.
  4. 如果您不直接使用 JDBC,而是使用 ORM,那可能会有问题.例如,Hibernate 社区表示在事务之外工作可能会导致不可预测的行为.这是因为 Hibernate 会打开事务,但不会自行关闭它,因此连接将返回到连接池,而事务未提交.那会发生什么?JDBC 保持沉默,因此这是特定于实现的(MySQL 回滚事务,Oracle 会提交它).这也可以在连接池级别进行配置(例如,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 your architecture is cumbersome and some team members may choose to put modification query where it's not expected, 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 中的事务进行只读操作?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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