论坛首页 Java企业应用论坛

hibernate一直的疑问

浏览 15063 次
精华帖 (2) :: 良好帖 (0) :: 新手帖 (3) :: 隐藏帖 (0)
作者 正文
   发表时间:2008-10-10  
hibernate中,当一个对象持久化将数据库读取后,并将数据保存进缓存中,当第二次读取数据时,它就直接去缓存中取数据了,这点没错吧

用户A访问A机,创建了一个session.检索tableA并对检索结果,持久化.
用户B访问B机,创建了一个session.并对tableA做更新操作.
用户A再次访问持久话的tableA.如果他从缓存中读取tableA的话.不是无法看到.用户B对tableA做的操作了吗?
   发表时间:2008-10-10  
你这里说的缓存应该是session缓存或者叫一级缓存
这个问题叫“脏读”,不是hibernate特有的问题,jdbc也一样
脏读一般情况下是可以接受的,
如果不能接受脏读,可以用悲观锁
如果脏读会导致更新丢失,可以采用乐观锁(比悲观锁代价小)
0 请登录后投票
   发表时间:2008-10-10  
也可以考虑用分布式二级缓存(比如EhCache或MemCached)或JVM集成(比如TerraCotta)来解决脏读问题,不过肯定要付出相应的代价
0 请登录后投票
   发表时间:2008-10-10  

daquan198163 写道
你这里说的缓存应该是session缓存或者叫一级缓存
这个问题叫“脏读”,不是hibernate特有的问题,jdbc也一样
脏读一般情况下是可以接受的,
如果不能接受脏读,可以用悲观锁
如果脏读会导致更新丢失,可以采用乐观锁(比悲观锁代价小)

是说1级缓存啊2级的官方说法就是不支持集群啊

我这里的问题不是处理排他的问题啊!即不是悲观乐观锁的问题啊!
并且这跟集群也没关系啊!单机也会出现这个问题啊~~!即a,b两用户机同时在浏览一个页面
a用户做了更新操作,b用户如果不刷新直接提交,就会在不知道数据变化的情况下操作了数据!



由于我只一次实际用过hb,其他都是书上看的!
所以以我对hb的理解总在这里很困惑
上面说的脏读的情况只可能发生在并发比较大的地方.如多人共同浏览一个页面.或者用户a在更新的一瞬间之前,
用户b访问该数据(可能性非常低)并且这些都可以用乐观锁时间戳处理!
但是hb在集群的情况下

1.用户A访问集群中A机,创建了一个session.检索tableA并对检索结果,持久化.
持久化内容放入了A机的内存.

2.户B访问集群中B机,创建了一个session.并对tableA做更新操作. ,持久化.持久化内容放入了B机内存

3.用户A再次访问持久话的tableA.从A机内存中读取tableA.
得到tableA的句柄后.做一个很耗费时间的跟tableA无关的操作.这个时候tableA已经被集群中的其他用户操作了
无数次了啊!但是如果不每次都强制刷新重新读取tableA的话..该用户还用之前得到的句柄浏览tableA的话....就可能出现很多的漏读 脏读.但是如果每次加载表都刷新一次!hb很大一部分功能都形同虚设
2 请登录后投票
   发表时间:2008-10-10  
哦,这个意思啊
离线乐观锁可以解决
0 请登录后投票
   发表时间:2008-10-10  
3.用户A再次访问持久话的tableA.从A机内存中读取tableA.
不对吧,如果不开二级缓存,用户A再次访问tableA应该能读到最新数据
0 请登录后投票
   发表时间:2008-10-13  
nlvivian 写道

daquan198163 写道
你这里说的缓存应该是session缓存或者叫一级缓存
这个问题叫“脏读”,不是hibernate特有的问题,jdbc也一样
脏读一般情况下是可以接受的,
如果不能接受脏读,可以用悲观锁
如果脏读会导致更新丢失,可以采用乐观锁(比悲观锁代价小)

是说1级缓存啊2级的官方说法就是不支持集群啊

我这里的问题不是处理排他的问题啊!即不是悲观乐观锁的问题啊!
并且这跟集群也没关系啊!单机也会出现这个问题啊~~!即a,b两用户机同时在浏览一个页面
a用户做了更新操作,b用户如果不刷新直接提交,就会在不知道数据变化的情况下操作了数据!



由于我只一次实际用过hb,其他都是书上看的!
所以以我对hb的理解总在这里很困惑
上面说的脏读的情况只可能发生在并发比较大的地方.如多人共同浏览一个页面.或者用户a在更新的一瞬间之前,
用户b访问该数据(可能性非常低)并且这些都可以用乐观锁时间戳处理!
但是hb在集群的情况下

1.用户A访问集群中A机,创建了一个session.检索tableA并对检索结果,持久化.
持久化内容放入了A机的内存.

2.户B访问集群中B机,创建了一个session.并对tableA做更新操作. ,持久化.持久化内容放入了B机内存

3.用户A再次访问持久话的tableA.从A机内存中读取tableA.
得到tableA的句柄后.做一个很耗费时间的跟tableA无关的操作.这个时候tableA已经被集群中的其他用户操作了
无数次了啊!但是如果不每次都强制刷新重新读取tableA的话..该用户还用之前得到的句柄浏览tableA的话....就可能出现很多的漏读 脏读.但是如果每次加载表都刷新一次!hb很大一部分功能都形同虚设



要做耗时,且于数据库无关的操作干嘛还要持有session?
应该在做无关操作的时候释放session,等你拉屎回来再重新开启新session,就可以有效的避免了。
如果你的业务要求数据不能有脏读的情况完全可以用悲观锁解决嘛
0 请登录后投票
   发表时间:2008-10-14  
一级缓存的生命周期是不是session的生命周期啊?

如果是这样的话 我想就不存在LZ所说的问题了
0 请登录后投票
   发表时间:2008-10-14  
daquan198163 写道
哦,这个意思啊
离线乐观锁可以解决


哦,这个意思啊
离线乐观锁可以解决

什么意思啊?
0 请登录后投票
   发表时间:2008-10-14  
taupo 写道
nlvivian 写道

daquan198163 写道
你这里说的缓存应该是session缓存或者叫一级缓存
这个问题叫“脏读”,不是hibernate特有的问题,jdbc也一样
脏读一般情况下是可以接受的,
如果不能接受脏读,可以用悲观锁
如果脏读会导致更新丢失,可以采用乐观锁(比悲观锁代价小)

是说1级缓存啊2级的官方说法就是不支持集群啊

我这里的问题不是处理排他的问题啊!即不是悲观乐观锁的问题啊!
并且这跟集群也没关系啊!单机也会出现这个问题啊~~!即a,b两用户机同时在浏览一个页面
a用户做了更新操作,b用户如果不刷新直接提交,就会在不知道数据变化的情况下操作了数据!



由于我只一次实际用过hb,其他都是书上看的!
所以以我对hb的理解总在这里很困惑
上面说的脏读的情况只可能发生在并发比较大的地方.如多人共同浏览一个页面.或者用户a在更新的一瞬间之前,
用户b访问该数据(可能性非常低)并且这些都可以用乐观锁时间戳处理!
但是hb在集群的情况下

1.用户A访问集群中A机,创建了一个session.检索tableA并对检索结果,持久化.
持久化内容放入了A机的内存.

2.户B访问集群中B机,创建了一个session.并对tableA做更新操作. ,持久化.持久化内容放入了B机内存

3.用户A再次访问持久话的tableA.从A机内存中读取tableA.
得到tableA的句柄后.做一个很耗费时间的跟tableA无关的操作.这个时候tableA已经被集群中的其他用户操作了
无数次了啊!但是如果不每次都强制刷新重新读取tableA的话..该用户还用之前得到的句柄浏览tableA的话....就可能出现很多的漏读 脏读.但是如果每次加载表都刷新一次!hb很大一部分功能都形同虚设



要做耗时,且于数据库无关的操作干嘛还要持有session?
应该在做无关操作的时候释放session,等你拉屎回来再重新开启新session,就可以有效的避免了。
如果你的业务要求数据不能有脏读的情况完全可以用悲观锁解决嘛





先汗一个啊!
用户A 在A机
1.首先执行一个select tableA 获得持久化的tableA
2.用tableA的数据做一个耗时间的操作,得到结果C!
3.显示tableA的数据到表现层(此时应该还是用步骤1中持久化的tablea吧?)

如果用户B在B机.在用户A在A机做步骤2的同时!
删除了很多tableA的数据!

那用户A在A机的第三个步骤,就会显示出很多已经被用户B在B机已经删除的数据










0 请登录后投票
论坛首页 Java企业应用版

跳转论坛:
Global site tag (gtag.js) - Google Analytics