12
返回列表 发新帖
楼主: hbwp2008

丢失更新和乐观锁问题

[复制链接]
论坛徽章:
7
生肖徽章2007版:鸡
日期:2008-01-02 17:35:53生肖徽章2007版:猴
日期:2008-01-02 17:35:53生肖徽章2007版:鼠
日期:2008-01-02 17:35:53嫦娥
日期:2008-07-08 11:25:29奥运会纪念徽章:垒球
日期:2008-07-22 23:37:50奥运会纪念徽章:跳水
日期:2008-07-31 22:00:562010新春纪念徽章
日期:2010-01-04 08:33:08
11#
发表于 2008-4-8 21:41 | 只看该作者
丢失更新是指因为两个SESSION同时对同一行数据作更新,结果因为没有作锁定(比如FOR UPDATE),造成其中一个“丢失”掉了,其实没有真正的丢失,是做了两次,每次都实际更新了,
乐观锁,是ORACLE的锁定机制的一种,看棉花糖说的,就是不很强制的一种锁定机制,更灵活,节约资源,但也更容易出错。

使用道具 举报

回复
论坛徽章:
9
会员2007贡献徽章
日期:2007-09-26 18:42:10ITPUB新首页上线纪念徽章
日期:2007-10-20 08:38:44生肖徽章2007版:鸡
日期:2008-01-02 17:35:53奥运会纪念徽章:花样游泳
日期:2008-05-27 23:33:24奥运会纪念徽章:垒球
日期:2008-06-17 15:23:21奥运会纪念徽章:足球
日期:2008-07-14 17:22:53奥运会纪念徽章:跳水
日期:2008-08-06 16:18:33奥运会纪念徽章:曲棍球
日期:2008-09-11 10:05:202011新春纪念徽章
日期:2011-02-18 11:43:35
12#
发表于 2008-4-8 23:03 | 只看该作者
hard???   it's very easy?
session 1
time 1  select * from tab_name where id=100 and type='y';
time 3 update   table_name  set ...  where  id=100
commit
time 5  select * from tab_name where id=100
session  2  select * from tab_name where id=100
time 2 select * from tab_name where id=100 and type='y';
time 4 update   table_name  set ...  where  id=100
commit.

time 5  query time 4  data. no time 3 query data. for example.  sale tickets
.you can see all .

使用道具 举报

回复
论坛徽章:
20
2008新春纪念徽章
日期:2008-02-13 12:43:032009新春纪念徽章
日期:2009-01-04 14:52:28生肖徽章2007版:龙
日期:2009-05-19 14:26:20itpub13周年纪念徽章
日期:2014-10-05 19:41:35美羊羊
日期:2015-03-12 15:49:41慢羊羊
日期:2015-04-03 16:13:19
13#
 楼主| 发表于 2008-4-9 09:59 | 只看该作者
原帖由 tanfufa 于 2008-4-8 23:03 发表
hard???   it's very easy?
session 1
time 1  select * from tab_name where id=100 and type='y';
time 3 update   table_name  set ...  where  id=100
commit
time 5  select * from tab_name where id=100
session  2  select * from tab_name where id=100
time 2 select * from tab_name where id=100 and type='y';
time 4 update   table_name  set ...  where  id=100
commit.

time 5  query time 4  data. no time 3 query data. for example.  sale tickets
.you can see all .



  thanks!!

使用道具 举报

回复
论坛徽章:
20
2008新春纪念徽章
日期:2008-02-13 12:43:032009新春纪念徽章
日期:2009-01-04 14:52:28生肖徽章2007版:龙
日期:2009-05-19 14:26:20itpub13周年纪念徽章
日期:2014-10-05 19:41:35美羊羊
日期:2015-03-12 15:49:41慢羊羊
日期:2015-04-03 16:13:19
14#
 楼主| 发表于 2008-4-9 10:41 | 只看该作者
原帖由 棉花糖ONE 于 2008-4-8 20:31 发表
一个再你做某个操作之前就把表锁住,比如在做dml之前先select for update住,这个就是悲观锁定机制
一个是在你做某个动作的时候直接判断,乐观锁定,通过检验版本,row_scn之类的东西实现



能不能细讲一下乐观锁定检验版本,row_scn之类的东西实现? 谢谢!

使用道具 举报

回复
论坛徽章:
20
2008新春纪念徽章
日期:2008-02-13 12:43:032009新春纪念徽章
日期:2009-01-04 14:52:28生肖徽章2007版:龙
日期:2009-05-19 14:26:20itpub13周年纪念徽章
日期:2014-10-05 19:41:35美羊羊
日期:2015-03-12 15:49:41慢羊羊
日期:2015-04-03 16:13:19
15#
 楼主| 发表于 2008-4-9 10:43 | 只看该作者
原帖由 SingleLove 于 2008-4-5 17:01 发表
LZ看看这个
http://singlelove1983.blog.163.c ... 904720082263256123/



看了一下. 他乐观锁讲得不够详细. 现在想请教大家的是乐观锁有三种判断方式他是否实现乐观锁的, 请高人详细讲解. 谢谢

使用道具 举报

回复
论坛徽章:
7
生肖徽章2007版:鸡
日期:2008-01-02 17:35:53生肖徽章2007版:猴
日期:2008-01-02 17:35:53生肖徽章2007版:鼠
日期:2008-01-02 17:35:53嫦娥
日期:2008-07-08 11:25:29奥运会纪念徽章:垒球
日期:2008-07-22 23:37:50奥运会纪念徽章:跳水
日期:2008-07-31 22:00:562010新春纪念徽章
日期:2010-01-04 08:33:08
16#
发表于 2008-4-9 10:57 | 只看该作者
原帖由 hbwp2008 于 2008-4-9 10:43 发表



看了一下. 他乐观锁讲得不够详细. 现在想请教大家的是乐观锁有三种判断方式他是否实现乐观锁的, 请高人详细讲解. 谢谢

常用的做法来实现。

[1]第一种就是在数据取得的时候把整个数据都copy到应用中,在进行提交的时候比对当前数据库中的数据和开始的时候更新前取得的数据。当发现两个数据一模一样以后,就表示没有冲突可以提交,否则则是并发冲突,需要去用业务逻辑进行解决。

[2]第二种乐观锁的做法就是采用版本戳,这个在Hibernate中得到了使用。采用版本戳的话,首先需要在你有乐观锁的数据库table上建立一个新的column,比如为number型,当你数据每更新一次的时候,版本数就会往上增加1。比如同样有2个session同样对某条数据进行操作。两者都取到当前的数据的版本号为1,当第一个session进行数据更新后,在提交的时候查看到当前数据的版本还为1,和自己一开始取到的版本相同。就正式提交,然后把版本号增加1,这个时候当前数据的版本为2。当第二个session也更新了数据提交的时候,发现数据库中版本为2,和一开始这个session取到的版本号不一致,就知道别人更新过此条数据,这个

时候再进行业务处理,比如整个Transaction都Rollback等等操作。在用版本戳的时候,可以在应用程序侧使用版本戳的验证,也可以在数据库侧采用Trigger(触发器)来进行验证。不过数据库的Trigger的性能开销还是比较的大,所以能在应用侧进行验证的话还是推荐不用Trigger。

[3]第三种做法和第二种做法有点类似,就是也新增一个Table的Column,不过这次这个column是采用timestamp型,存储数据最后更新的时间。在Oracle9i以后可以采用新的数据类型,也就是timestamp with time zone类型来做时间戳。这种Timestamp的数据精度在Oracle的时间类型中是最高的,精确到微秒(还没与到纳秒的级别),一般来说,加上数据库处理时间和人的思考动作时间,微秒级别是非常非常够了,其实只要精确到毫秒甚至秒都应该没有什么问题。和刚才的版本戳类似,也是在更新提交的时候检查当前数据库中数据的时间戳和自己更新前取到的时间戳进行对比,如果一致则OK,否则就是版本冲突。如果不想把代码写在程序中或者由于别的原因无法把代码写在现有的程序中,也可以把这个时间戳乐观锁逻辑写在Trigger或者存储过程中。
PS: 论坛中不可能给的多么现成的,如果那样论坛会把人都搞成笨蛋的,更多的只是给你一个思路,上面的问题,其实思路给的已经很清楚了,自己还有兴趣的话,可以GOOGLE一下,比别人给你的东西要清晰的多,

使用道具 举报

回复

您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

TOP技术积分榜 社区积分榜 徽章 团队 统计 知识索引树 积分竞拍 文本模式 帮助
  ITPUB首页 | ITPUB论坛 | 数据库技术 | 企业信息化 | 开发技术 | 微软技术 | 软件工程与项目管理 | IBM技术园地 | 行业纵向讨论 | IT招聘 | IT文档
  ChinaUnix | ChinaUnix博客 | ChinaUnix论坛
CopyRight 1999-2011 itpub.net All Right Reserved. 北京盛拓优讯信息技术有限公司版权所有 联系我们 未成年人举报专区 
京ICP备16024965号-8  北京市公安局海淀分局网监中心备案编号:11010802021510 广播电视节目制作经营许可证:编号(京)字第1149号
  
快速回复 返回顶部 返回列表