gpt4 book ai didi

java - Hibernate 一级和二级缓存如何与多个 session 一起工作

转载 作者:行者123 更新时间:2023-11-30 11:16:47 27 4
gpt4 key购买 nike

我是 Hibernate 的新手,我知道一级缓存是 session 范围的,二级缓存是跨 session 的,假设我有一个包含字段 Id 和 Name 的实体 Person。

  1. 创建session1并加载一个人,Id=1, Name="AAA"

  2. 创建 session 2,更新此人,
    session.saveOrUpdate(人), Id=1, Name="BBB"

  3. 回到 session1 再次更新,session.saveOrUpdate(人), Id=1, Name="AAA"


下面是我对 hibernate 内部做什么的猜测:

第一步

hibernate搜索session1的level1缓存,什么都没有

hibernate 搜索二级缓存,什么都没有

hibernate 搜索数据库

实体存储在level1和level2缓存中

现在 level1 和 level2 缓存都有一个实体,person with id=1 and name="AAA"


第 2 步

hibernate搜索session2的level1缓存,什么都没有

hibernate 搜索二级缓存,获取实体(id=1 name="AAA"的人)

将这个实体存入session2的一级缓存

将此实体与 session.saveOrUpdate(person) 的参数进行比较

名称已更改,因此需要更新

session2的一级缓存更新

二级缓存已更新

数据库已更新


第三步

hibernate搜索session1的一级缓存,得到实体(id=1,name="AAA"的人)

将此实体与 session.saveOrUpdate(person) 的参数进行比较

没有改变

所以数据库不会更新?


我会尝试编写一些测试代码,但在此之前,如果有人能指出上面的任何误解,我将不胜感激,这将有助于我更深入地了解 hibernate 缓存。

提前致谢。

最佳答案

你的大部分假设都是正确的,除了以下几个:

  • saveOrUpdate 不用于传播更新更改,而是用于:

    1. 保留一个临时实体(例如保存)
    2. 重新附加一个分离的实体(例如更新)

当您在 session 中加载一个实体时,它会被加载到一级缓存中,并且您对该实体所做的任何更改都将在刷新期间被发现并传播。所以在这种情况下您不必调用 saveOrUpdate。

  • 在第 3 步的示例中,Hibernate 未检测到您的第一个 session 中的任何更改,因此它没有任何要更新的内容,即使其他 session 已经更新了该实体。

    为了防止“丢失更新”,Hibernates 提供:

    1. 乐观锁(@Version)
    2. 悲观锁(指示数据库获取锁)

如果您选择乐观锁定,并在第 3 步中将实体名称更改为“CCC”,您将获得 org.hibernate.StaleObjectStateException(在刷新期间),表明您拥有您尝试访问的实体的陈旧版本保存。

关于java - Hibernate 一级和二级缓存如何与多个 session 一起工作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24694379/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com