【问题标题】:Hibernate second level cache and RR transaction isolationHibernate 二级缓存和 RR 事务隔离
【发布时间】:2012-04-05 14:07:10
【问题描述】:

如果两个事务(都在 RR 隔离级别)请求相同的项目,该项目是 2 级缓存,然后他们修改并存储该项目。现在,为了读取该项目,他们没有运行任何 SQL,因为它已被缓存;那么在这种情况下,他们真的会启动数据库事务吗?当他们提交更改时,他们会遇到丢失更新的问题吗?

【问题讨论】:

    标签: java hibernate second-level-cache transaction-isolation


    【解决方案1】:

    从悲观的角度来看:

    如果二级缓存被配置为参与事务,那么只有第一个获得写锁的缓存才能修改缓存对象,然后将更改写入数据库。当第二个事务想要获取写锁时,它必须等到第一个事务结束并释放它。

    使用乐观锁定,我猜应该会发生并发修改异常(或类似名称),并且第二个事务将重试该操作。

    【讨论】:

    • 假设缓存是读写的。事务不会在 DB 中获得共享读锁,因为它们永远不会去 DB 读取。假设t1先更新,所以它锁定对象,获取DB写锁,更新DB并释放DB写锁和对象锁; t2 然后锁定对象,获取 DB 写锁,更新 DB 并释放 DB 写锁和对象锁。那么 t2 不会覆盖 t1 的更改吗?那么即使隔离级别是 RR,我们不会丢失更新吗?
    • 在您提到的示例中,t1 先写入,然后再写入 t2。丢失更新问题发生在 t2 在读取 t1 更改之前的值之后写入。在您的示例中,没有事务读取任何内容,它们只写入。如果 t2 在 t1 更新它之前读取了该值,那么 t1 将无法进行更新,因为 t2 有一个读锁。而且写锁不能和读锁共享。
    • 好吧,由于它们都是从缓存中读取的,所以它们会得到相同的值。所以 t2 将在 t1 写入之前读取该值。然后 t1 写入它,然后 t2 写入它。由于他们没有使用任何共享读锁(因为值来自缓存而不是数据库),这不会导致 t1 丢失更新吗?
    • 他们将在缓存对象上拥有一个共享读锁。锁不仅仅存在于数据库中。当然,这是假设缓存是事务性配置的。事务缓存的例子有 Infinispan 和 EhCache。阅读:ehcache.org/documentation/apis/jta
    • 我最熟悉的是不支持读写策略的Infinispan。另一方面,它看起来像 EhCache。阅读其文档ehcache.org/documentation/user-guide/hibernate,关于读写的部分,它说:“在并发写入的情况下,可重复读隔离受到损害”。所以看起来可能会丢失更新。
    猜你喜欢
    • 2013-08-20
    • 1970-01-01
    • 2014-11-28
    • 2011-12-18
    • 2012-12-12
    • 2015-05-14
    • 2011-03-19
    • 2016-03-24
    • 2011-05-09
    相关资源
    最近更新 更多