我们大多数人可能正在使用Spring和Hibernate进行数据访问。 我试图了解一些Spring Transaction Manager的内部结构。
根据Spring API,它支持不同的隔离级别 - doc 但我无法找到明确的信息,这些信息在哪些情况下对提高性能非常有帮助。
我知道来自readOnly
的{{1}}参数可以帮助我们将不同的TxManagers用于只读数据并且可以利用良好的性能。但它Spring Transaction
表来获取数据以避免脏读/非提交读 - doc。
假设在很少的情况下,我们可能希望盲目地将记录插入表中并在不锁定表的情况下检索信息,我们只是插入并读取[仅附加]。我们可以使用更好的隔离来获得任何性能吗?
答案 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
可以为当前正在运行的事务应用特定的隔离级别。WebLogicJtaTransactionManager
。