繁体   English   中英

Spring 事务隔离级别

[英]Spring Transaction Isolation Level

我们大多数人可能使用 Spring 和 Hibernate 进行数据访问。 我试图了解 Spring Transaction Manager 的一些内部结构。

根据 Spring API,它支持不同的隔离级别 - doc但我找不到明确的信息,这些信息在哪些情况下真正有助于获得性能改进。

我知道Spring Transaction中的readOnly参数可以帮助我们使用不同的 TxManager 来只读数据,并且可以利用良好的性能。 但它locks表以获取数据以避免脏读/未提交的读取 - doc

假设,在少数情况下,我们可能希望盲目地将记录插入表中并在不锁定表的情况下检索信息,这种情况下我们从不更新表数据,我们只是插入和读取 [仅追加]。 我们可以使用更好的隔离来获得任何性能吗?

  1. 正如您从参考链接之一看到的,我们真的需要实现/编写我们自己的 CustomJPADiaelect 吗?
  2. 什么是更适合我的要求的隔离?

Read-only允许某些优化,例如禁用脏检查,当您不打算更改实体时,您应该完全使用它。

每个隔离级别定义了数据库必须施加多少锁定以确保防止数据异常。

大多数数据库使用MVCC (Oracle、PostgreSQL、MySQL),因此读者不锁定编写者编写者不锁定读者 正如您在以下示例中看到的那样只有writers 锁定了 writers

REPEATABLE_READ不必持有来防止并发事务修改当前事务加载的行。 MVCC 引擎允许其他事务读取行的已提交状态,即使您当前的事务已更改它但尚未提交(MVCC 使用撤消日志来恢复pending changed行的先前版本)。

在您的用例中,您应该使用READ_COMMITTED因为它比其他更严格的隔离级别更好地扩展,并且您应该使用乐观锁定来防止长时间对话中丢失更新。


更新

@Transactional(isolation = Isolation.SERIALIZABLE)设置为 Spring bean 具有不同的行为,具体取决于当前的事务类型:

  • 对于RESOURCE_LOCAL事务, JpaTransactionManager可以为当前运行的事务应用特定的隔离级别。
  • 对于 JTA 资源,事务范围的隔离级别不会传播到底层数据库连接,因为这是默认的 JTA 事务管理器行为。 您可以按照WebLogicJtaTransactionManager的示例覆盖它。

实际上readOnly=true不会对数据库表造成任何锁争用,因为根本不需要锁定 - 数据库能够忽略所有新更改而恢复到记录的先前版本。

当 readOnly 为 true 时,您将在当前的 Hibernate Session 中将刷新模式设为FlushMode.NEVER ,以防止会话提交事务。 另外,在JDBC Connection上会调用setReadOnly(true) ,这也是对底层数据库不要提交更改的提示。

所以readOnly=true正是您正在寻找的(例如SERIALIZED隔离级别)。

是一个很好的解释。

暂无
暂无

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

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