精华帖 (2) :: 良好帖 (0) :: 新手帖 (3) :: 隐藏帖 (0)
|
|
---|---|
作者 | 正文 |
发表时间:2008-10-10
用户A访问A机,创建了一个session.检索tableA并对检索结果,持久化. 用户B访问B机,创建了一个session.并对tableA做更新操作. 用户A再次访问持久话的tableA.如果他从缓存中读取tableA的话.不是无法看到.用户B对tableA做的操作了吗? 声明:ITeye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
推荐链接
|
|
返回顶楼 | |
发表时间:2008-10-10
你这里说的缓存应该是session缓存或者叫一级缓存
这个问题叫“脏读”,不是hibernate特有的问题,jdbc也一样 脏读一般情况下是可以接受的, 如果不能接受脏读,可以用悲观锁 如果脏读会导致更新丢失,可以采用乐观锁(比悲观锁代价小) |
|
返回顶楼 | |
发表时间:2008-10-10
也可以考虑用分布式二级缓存(比如EhCache或MemCached)或JVM集成(比如TerraCotta)来解决脏读问题,不过肯定要付出相应的代价
|
|
返回顶楼 | |
发表时间: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很大一部分功能都形同虚设 |
|
返回顶楼 | |
发表时间:2008-10-10
哦,这个意思啊
离线乐观锁可以解决 |
|
返回顶楼 | |
发表时间:2008-10-10
3.用户A再次访问持久话的tableA.从A机内存中读取tableA.
不对吧,如果不开二级缓存,用户A再次访问tableA应该能读到最新数据 |
|
返回顶楼 | |
发表时间: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,就可以有效的避免了。 如果你的业务要求数据不能有脏读的情况完全可以用悲观锁解决嘛 |
|
返回顶楼 | |
发表时间:2008-10-14
一级缓存的生命周期是不是session的生命周期啊?
如果是这样的话 我想就不存在LZ所说的问题了 |
|
返回顶楼 | |
发表时间:2008-10-14
daquan198163 写道 哦,这个意思啊
离线乐观锁可以解决 哦,这个意思啊 离线乐观锁可以解决 什么意思啊? |
|
返回顶楼 | |
发表时间: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机已经删除的数据 |
|
返回顶楼 | |