悲观锁:

  顾名思义,很悲观,就是每次拿数据的时候都认为别的线程会修改数据,所以在每次拿的时候都会给数据上锁。上锁之后,当别的线程想要拿数据时,就会阻塞,直到给数据上锁的线程将事务提交或者回滚。传统的关系型数据库里就用到了很多这种锁机制,比如行锁,表锁,共享锁,排他锁等,都是在做操作之前先上锁。
  
行锁:
  下面演示行锁,打开两个mysql命令行界面,两个线程分别执行如下操作:(左边先执行)
  
  
悲观锁,乐观锁,行锁,表锁,页锁,共享锁,排他锁 数据库 数据库学习 悲观锁 乐观锁 ...
  
  左边的线程,在事务中通过select for update语句给sid = 1的数据行上了锁。右边的线程此时可以使用select语句读取数据,但是如果也使用select for update语句,就会阻塞,使用update,add,delete也会阻塞。
  当左边的线程将事务提交(或者回滚),右边的线程就会获取锁,线程不再阻塞:
  
  
悲观锁,乐观锁,行锁,表锁,页锁,共享锁,排他锁 数据库 数据库学习 悲观锁 乐观锁 ...
  
  此时,右边的线程获取锁,左边的线程如果执行类似操作,也会被阻塞:
  
  
悲观锁,乐观锁,行锁,表锁,页锁,共享锁,排他锁 数据库 数据库学习 悲观锁 乐观锁 ...
  
表锁:
  
  上述例子中,如果使用如下语句就是使用的表锁:
select * from student for update;
页锁:
  
  行锁锁指定行,表锁锁整张表,页锁是折中实现,即一次锁定相邻的一组记录。
  
共享锁:
  
  共享锁又称为读锁,一个线程给数据加上共享锁后,其他线程只能读数据,不能修改。
  
排他锁:
  
  排他锁又称为读锁,和共享锁的区别在于,其他线程既不能读也不能修改。
  
乐观锁:
  
  乐观锁其实不会上锁。顾名思义,很乐观,它默认别的线程不会修改数据,所以不会上锁。只是在更新前去判断别的线程在此期间有没有修改数据,如果修改了,会交给业务层去处理。
  常用的实现方式是使用版本戳,例如在一张表中添加一个整型字段version,每更新version++,比如某个时刻version=1,线程A读取了此version=1,线程B也读取了此version=1,当线程A更新数据之前,判断version仍然为1,更新成功,version++变为2,但是当线程B再提交更新时,发现version变为2了,与之前读的version=1不一致,就知道有别的线程更新了数据,这个时候就会进行业务逻辑的处理。
  
通常情况下,写操作较少时,使用乐观锁,写操作较多时,使用悲观锁。

本文数据库(综合)相关术语:系统安全软件

主题: 数据数据库其实
分页:12
转载请注明
本文标题:悲观锁,乐观锁,行锁,表锁,页锁,共享锁,排他锁 数据库 数据库学习 悲观锁 乐观锁 ...
本站链接:http://www.codesec.net/view/533899.html
分享请点击:


1.凡CodeSecTeam转载的文章,均出自其它媒体或其他官网介绍,目的在于传递更多的信息,并不代表本站赞同其观点和其真实性负责;
2.转载的文章仅代表原创作者观点,与本站无关。其原创性以及文中陈述文字和内容未经本站证实,本站对该文以及其中全部或者部分内容、文字的真实性、完整性、及时性,不作出任何保证或承若;
3.如本站转载稿涉及版权等问题,请作者及时联系本站,我们会及时处理。
登录后可拥有收藏文章、关注作者等权限...
技术大类 技术大类 | 数据库(综合) | 评论(0) | 阅读(82)