乐观与悲观
snowind9
2007-08-30
以前一直在思考一个问题。今天在跟joard讨论中,终于知道解决办法了。感谢joard
在做数据库的排他竞合的时候总会在数据表中增加一个冗余字段。版本号啦,时间戳啦,用这些冗余来做数据的更新竞合判断,防止并发时数据的丢失。 但是只用这种乐观锁来做也会有问题:就是说,在同一时间两个用户同时修改一个数据,恰恰同时的来判断时间戳(版本号)相同与否,当然因为都是原始数据,都会同事通过检验,然后就会出严重的问题,数据的丢失-第一个进行update的人的数据就被后面的人给蒸发掉了。我曾试图在程序中用同步来控制,但是发现效果不是很好,并且影响框架的结构,造成混乱,不优雅,也不便捷(因为需要改的地方实在很多)。 在跟jorad讨论的时候,发现他们开发的时候页用早就被我抛弃的for update,做悲观锁,突然明白了。可以在检查时间戳(版本号)的时候用悲观锁锁定,锁定后别人是无法在通过for update 读出数据的。阻塞了别人的验证,自己的验证通过后,提交,然后解锁。解锁后,其他人取得修改后的数据,判断时间戳(版本号)不通过,于是就在数据库曾解决了极端并发的这个问题。并且由于验证时间戳(版本号)到提交的间隔非常小(锁定的时间近似等于提交的时间与间隔时间之和),并不会对数据库的并发产生额外的巨大影响。可以说是一个较好的解决方案。 但有一个问题是joard这里使用for update wait 30 的wait 30 在这里的左右有多大呢?什么情况下他人的锁定时间会超过30秒那么多呢?假如有产生死锁的可能,wait 30 只能是让新的查询在30秒后响应,对死锁也没有任何帮助。不是很清除这个作用。大概是为了防止死锁的一种安全措施吧。防止占用着资源,并无限的等待。 并且程序方面如何对应的“ORA-30006: resource busy; acquire with WAIT timeout expired”这个错误的还不知道。要解决的问题还有很多。请大家指点。 |
|
Spike
2007-09-03
kao
什么时候发的阿 完全没注意到这个帖子 wait 30 这里的单位是毫秒吧 |
|
snowind9
2007-09-05
30秒 只得是你被阻塞的最大等待时间。就是别人在锁表。你等待的时间
|