博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
乐观锁和悲观锁【转】
阅读量:6837 次
发布时间:2019-06-26

本文共 1064 字,大约阅读时间需要 3 分钟。

 

在多用户环境中,在同一时间可能会有多个用户更新相同的记录,这会产生冲突。这就是著名的并发性问题。

典型的冲突有:

l 丢失更新:一个事务的更新覆盖了其它事务的更新结果,就是所谓的更新丢失。例如:用户A把值从6改为2,用户B把值从2改为6,则用户A丢失了他的更新。

l 脏读:当一个事务读取其它完成一半事务的记录时,就会发生脏读取。例如:用户A,B看到的值都是6,用户B把值改为2,用户A读到的值仍为6。

为了解决这些并发带来的问题。 我们需要引入并发控制机制。

悲观锁:假定会发生并发冲突,屏蔽一切可能违反数据完整性的操作。[1]

乐观锁:假设不会发生并发冲突,只在提交操作时检查是否违反数据完整性。[1] 乐观锁不能解决脏读的问题。

乐观锁应用

1.      使用自增长的整数表示数据版本号。更新时检查版本号是否一致,比如数据库中数据版本为6,更新提交时version=6+1,使用该version值(=7)与数据库version+1(=7)作比较,如果相等,则可以更新,如果不等则有可能其他程序已更新该记录,所以返回错误。

2.      使用时间戳来实现.

注:对于以上两种方式,Hibernate自带实现方式:在使用乐观锁的字段前加annotation: @Version, Hibernate在更新时自动校验该字段。

悲观锁应用

需要使用数据库的锁机制,比如SQL SERVER 的TABLOCKX(排它表锁) 此选项被选中时,SQL  Server  将在整个表上置排它锁直至该命令或事务结束。这将防止其他进程读取或修改表中的数据。

SqlServer中使用

Begin Tran

select top 1 @TrainNo=T_NO
         from Train_ticket   with (UPDLOCK)   where S_Flag=0
      update Train_ticket
         set T_Name=user,
             T_Time=getdate(),
             S_Flag=1
         where T_NO=@TrainNo
commit

我们在查询的时候使用了with (UPDLOCK)选项,在查询记录的时候我们就对记录加上了更新锁,表示我们即将对此记录进行更新. 注意更新锁和共享锁是不冲突的,也就是其他用户还可以查询此表的内容,但是和更新锁和排它锁是冲突的.所以其他的更新用户就会阻塞.

在实际生产环境里边,如果并发量不大且不允许脏读,可以使用悲观锁解决并发问题;但如果系统的并发非常大的话,悲观锁定会带来非常大的性能问题,所以我们就要选择乐观锁定的方法.

 

 

转载地址:http://kgmkl.baihongyu.com/

你可能感兴趣的文章
错误总结
查看>>
Delphi7 (第一天:类的编写)续
查看>>
单片机基础
查看>>
ZOJ 1027 Human Gene Functions(动态规划LCS)
查看>>
变量、中文-「译」javascript 的 12 个怪癖(quirks)-by小雨
查看>>
合作开发用到的几个 设计模式
查看>>
[iOS] 在UIToolBar中增加UILabel等控件(xib/storyboard图形界面方式)
查看>>
宋体节点hdoj 1520 Anniversary party(树形dp)
查看>>
优化网站设计(七):避免在CSS中使用表达式
查看>>
让你的网站拥有微博(weibo.com)关注图标
查看>>
hadoop基本命令
查看>>
若不能连接到sql server的localhost
查看>>
JavaScript无提示关闭窗口(兼容IE/Firefox/Chrome)
查看>>
Winform窗口里的嵌入WPF的UserControl,关闭Winform父窗体的方法
查看>>
JavaScript – 6.JS面向对象基础(*) + 7.Array对象 + 8.JS中的Dictionary + 9.数组、for及其他...
查看>>
格式资料python sqlalchemy 查询结果转化为 Json格式
查看>>
超链接浏览<meta name="format-detection"/> 的用法
查看>>
请求网络网络编程
查看>>
文件目录Android SDK目录结构
查看>>
Asp.net Web.Config - 配置元素customErrors
查看>>