[英]Spring Transaction Isolation Level
我们大多数人可能使用 Spring 和 Hibernate 进行数据访问。 我试图了解 Spring Transaction Manager 的一些内部结构。
根据 Spring API,它支持不同的隔离级别 - doc但我找不到明确的信息,这些信息在哪些情况下真正有助于获得性能改进。
我知道Spring Transaction
中的readOnly
参数可以帮助我们使用不同的 TxManager 来只读数据,并且可以利用良好的性能。 但它locks
表以获取数据以避免脏读/未提交的读取 - doc 。
假设,在少数情况下,我们可能希望盲目地将记录插入表中并在不锁定表的情况下检索信息,这种情况下我们从不更新表数据,我们只是插入和读取 [仅追加]。 我们可以使用更好的隔离来获得任何性能吗?
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
可以为当前运行的事务应用特定的隔离级别。WebLogicJtaTransactionManager
的示例覆盖它。实际上readOnly=true
不会对数据库表造成任何锁争用,因为根本不需要锁定 - 数据库能够忽略所有新更改而恢复到记录的先前版本。
当 readOnly 为 true 时,您将在当前的 Hibernate Session 中将刷新模式设为FlushMode.NEVER
,以防止会话提交事务。 另外,在JDBC Connection上会调用setReadOnly(true)
,这也是对底层数据库不要提交更改的提示。
所以readOnly=true
正是您正在寻找的(例如SERIALIZED
隔离级别)。
这是一个很好的解释。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.