Spring事务隔离级别

时间:2015-05-11 06:30:39

标签: java mysql spring hibernate transactions

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

根据Spring API,它支持不同的隔离级别 - doc 但我无法找到明确的信息,这些信息在哪些情况下对提高性能非常有帮助。

我知道来自readOnly的{​​{1}}参数可以帮助我们将不同的TxManagers用于只读数据并且可以利用良好的性能。但它Spring Transaction表来获取数据以避免脏读/非提交读 - doc

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

  1. 从其中一个参考链接看,我们真的需要实现/编写我们自己的CustomJPADiaelect吗?
  2. 对我的要求更好的隔离是什么?

2 个答案:

答案 0 :(得分:2)

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

如果readOnly为true,则当前Hibernate会话中的刷新模式为FlushMode.NEVER,阻止会话提交事务。此外,将在JDBC Connection上调用setReadOnly(true),这也是底层数据库不提交更改的提示。

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

Here是一个很好的解释。

答案 1 :(得分:2)

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

每个isolation level定义数据库必须锁定多少才能确保数据异常防止。

大多数数据库使用MVCC(Oracle,PostgreSQL,MySQL),因此读者不会锁定作者编写者不会锁定读者。正如您在the following example中看到的那样,只有作家锁定作家

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

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

更新

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

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