ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

乐观锁悲观锁

2019-05-08 11:53:54  阅读:202  来源: 互联网

标签:用户 更新 乐观 并发 version 冲突 悲观 数据


一、为什么需要锁(并发控制)

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

典型的冲突有:

  • 丢失更新:一个事务的更新覆盖了其它事务的更新结果,就是所谓的更新丢失。例如:用户A把值从6改为2,用户B把值从2改为6,则用户A丢失了他的更新。
  • 脏读:当一个事务读取其它完成一半事务的记录时,就会发生脏读取。例如:用户A,B看到的值都是6,用户B把值改为2,用户A读到的值仍为6。

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

二、并发控制机制

  • 乐观锁:假定不会发生并发冲突,只是在提交的时候检查是否违反的完整性【1】乐观锁不能解决脏读的问题;
  • 悲观锁:假定会发生并发冲突,屏蔽一切可能破坏数据完整性的操作;

三、乐观锁

乐观锁介绍:

乐观锁相对于悲观锁而言,乐观锁假设数据一般情况下不会发生冲突,所以在数据提交更新时候,才会正式的对数据的冲突与否进行检测,如果发现冲突了,则给用户返回错误信息,让用户决定如何去做,乐观锁主要有两种实现方式:

  1. 使用数据版本记录机制实现:何谓数据版本,即为数据增加一个版本标识,一般是通过为数据库表增加一个数字类型的“version”字段实现,当读取数据时,将version字段的值一同读出,数据每更新一次,对此version的值+1,当我们提交更新的时候,判断数据库表对应记录的当前版本信息与第一次取出时的版本信息是否一致,一致则更新,否则认为是过期数据。

 

如上图所示,如果更新操作顺序执行,则数据的版本(version)依次递增,不会产生冲突。但是如果发生有不同的业务操作对同一版本的数据进行修改,那么,先提交的操作(图中B)会把数据version更新为2,当A在B之后提交更新时发现数据的version已经被修改了,那么A的更新操作会失败。

给出查询和更新操作的执行sql

查询: select (status,status,version) from t_goods where id=#{id}

更新:

update t_goods set status=2,version=version+1 where id=#{id} and version=#{version};

那么我们在更新的时候需要传入的参数要加上“数据版本”这个字段。

2.乐观锁定的第二种实现方式和第一种差不多,同样是在需要乐观锁控制的table中增加一个字段,名称无所谓,字段类型使用时间戳(timestamp), 和上面的version类似,也是在更新提交的时候检查当前数据库中数据的时间戳和自己更新前取到的时间戳进行对比,如果一致则OK,否则就是版本冲突。

四、悲观锁应用

需要使用数据库的锁机制,例如

select * from

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

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

五、结论

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

 

标签:用户,更新,乐观,并发,version,冲突,悲观,数据
来源: https://blog.csdn.net/StringBuff/article/details/89520357

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有