文档章节

数据库锁:乐观锁和悲观锁,共享锁和排它锁,行级锁和表级锁

vshcxl
 vshcxl
发布于 2016/07/13 11:20
字数 1437
阅读 142
收藏 2
点赞 0
评论 0

一、悲观锁和乐观锁

  我们经常在开发中遇到数据库并发处理时,处理不一致的问题。需要对程序做并发控制。
典型的并发时出现的冲突有两种:
1、丢失更新:一个事务的更新覆盖了其它事务的更新结果,就是所谓的更新丢失。
例如X=0  A1把X=X+1  A2也设置X=X+1    如果A1和A2同时执行,可能出现最终X=1的情况。而我们需要得到的是X=2  。   这就需要update处理为串行化的。
2、脏读:读到的数据可能是旧的。    初使X=0    A1把X设置为1,A2读取时X是1,但A1后面又修改成了2,或回滚到了0,那么A2读取的数据就是脏数据。
A2读取的是未提交的数据。一般数据库不会设为读未提交,所以一般不会出现脏读。

那什么是乐观锁,什么是悲观锁。

悲观锁:需要使用数据库的锁机制,如数据库有表级排它锁,有行级排它锁。
假定一切操作都可能发现并发冲突,所以采取悲观态度。通过加锁,屏蔽一切可能违反数据完整性的操作
比方select * from table for update;  就是表锁,
select * from table where x = 1 for update; 就是行锁。
当使用for update后,其它会话还是可以执行select操作,但无法执行select xx for update操作,只有当前会话commit后,其它for update操作才会被执行。
典型例子可以参考quartz集群的锁机制:http://blog.itpub.net/11627468/viewspace-1764753/
当然,此时也不可以update,update需要等select xx for update 所在会话commit后才能执行。
注:mysql需要设置autocommit=0

乐观锁:其实不是真实的去锁住记录不让访问,或者不让更新。
假定操作很少发生冲突,一般对于读多写少的情况。只在提交操作时检查是否违反数据完整性。[1] 乐观锁不能解决脏读的问题。
可以通过版本号是否比上个版本号或者时间戳来实现。
对于冲突检测后的处理,需要业务逻辑去处理。

二、排它锁和共享锁
在数据库中有两种基本的锁类型:排它锁(Exclusive Locks,即X锁)和共享锁(Share Locks,即S锁)。
当数据对象被加上排它锁时,其他的事务不能对它读取和修改。加了共享锁的数据对象可以被其他事务读取,但不能修改。
数据库利用这两种基本的锁类型来对数据库的事务进行并发控制。


三、表级锁和行级锁

     DML锁的目的在于保证并发情况下的数据完整性,主要包括TM锁和TX锁,其中TM锁称为表级锁,TX锁称为事务锁或行级锁。
     当Oracle执行DML语句时,系统自动在所要操作的表上申请TM类型的锁。当TM锁获得后,系统再自动申请TX类型的锁,并将实际锁定的数据行的锁标志位进行置位。这样在事务加锁前检查TX锁相容性时就不用再逐行检查锁标志,而只需检查TM锁模式的相容性即可,大大提高了系统的效率。TM锁包括了SS、SX、S、X等多种模式,在数据库中用0-6来表示。不同的SQL操作产生不同类型的TM锁。

值  锁模式  锁描述  SQL
0 NONE 1  NULL  空  SELECT
2  SS(ROW-S)  行级共享锁
其他对象只能查询这些数据行  SELECT FOR UPDATE、LOCK FOR UPDATE、
LOCK ROW SHARE
3  SX(ROW-X)  行级排它锁
在提交前不允许做DML操作  INSERT、UPDATE、DELETE、
LOCK ROW SHARE
4  S(SHARE)  共享锁  CREATE INDEX、LOCK SHARE
5  SSX(S/ROW-X)  共享行级排它锁  LOCK SHARE ROW EXCLUSIVE
6  X(eXclusive)  排它锁  ALTER TABLE、DROP TABLE、DROP INDEX、
TRUNCATE TABLE、LOCK EXCLUSIVE

四、几个问题
1.UPDATE/DELETE操作会将RS锁定,直至操作被COMMIT或者ROLLBACK;
若操作未COMMIT之前其他session对同样的RS做变更操作,则操作会被hold,直至前session的UPDATE/DELETE操作被COMMIT;


2.session内外SELECT的RS范围
前提:INSERT、UPDATE操作未COMMIT之前进行SELECT;
若在同一session内,SELECT出来的RS会包括之前INSERT、UPDATE影响的记录;
若不在同一session内,SELECT出来的RS不会包括未被COMMIT的记录;


3.SELECT.... FOR UPDATE [OF cols] [NOWAIT/WAIT] [SKIP LOCKED]
OF cols:只锁定指定字段所在表的RS,而没有指定的表则不会锁定,只会在多表联合查询时出现;
NOWAIT:语句不会hold,而是直接返回错误ORA-00054: resource busy and acquire with NOWAIT specified;
WAIT N:语句被hold N秒,之后返回错误ORA-30006: resource busy; acquire with WAIT timeout expired;
SKIP LOCKED:不提示错误,而是直接返回no rows selected;
以上几个选项可以联合使用的,比较推荐的有:
SELECT.... FOR UPDATE NOWAIT:对同一RS执行该SQL时,直接返回错误;
SELECT.... FOR UPDATE NOWAIT SKIP LOCKED:对同一RS执行该SQL时,直接返回空行;
PS:当RS被LOCK住之后,只对同样请求LOCK的语句有效,对无需LOCK的SELECT语句并没有任何影响;





以上悲观锁和乐内容参考:
http://www.cnblogs.com/guyufei/archive/2011/01/10/1931632.html
spring锁实现参数:
http://blog.itpub.net/12158104/viewspace-374745
关于隔离级别可以参考:
http://blog.itpub.net/11627468/viewspace-1793036/
关于数据库的锁可以参考:
http://zhidao.baidu.com/link?url=zRnaslJ8INtEviT--BzrT2bMOqf4LJQzL-NQg2ECu6l-s-xPHi11bBlNjN2_zyNrwd9M0ZnbelQntmfYPB0ifq

© 著作权归作者所有

共有 人打赏支持
vshcxl
粉丝 19
博文 278
码字总数 32372
作品 0
浦东
高级程序员
MySQL数据库的锁机制

在并发访问情况下,很有可能出现不可重复读等等读现象。为了更好的应对高并发,封锁、时间戳、乐观并发控制(乐观锁)、悲观并发控制(悲观锁)都是并发控制采用的主要技术方式。 锁分类 ①、按操...

Javahih ⋅ 01/02 ⋅ 0

oracle的锁机制

oracle数据库是一个多用户使用的共享资源。当多个用户并发地存取数据时,在数据库中就会产生多个事务同时存取同一数据的情况。若对并发操作不加控制就可能会读取和存储不正确的数据,破坏数据...

柳哥 ⋅ 2014/06/29 ⋅ 0

数据库锁总结

一直想写一篇关于数据库锁的相关总结文章,因为平时看数据库相关的博文的时候,会时不时看到某个数据库锁,一直没弄清楚各种锁的关系,下面就大概总结一下,希望园友提出问题。   数据库锁...

17099933344 ⋅ 2017/08/03 ⋅ 0

数据库中的锁

锁的概述一. 为什么要引入锁多个用户同时对数据库的并发操作时会带来以下数据不一致的问题:丢失更新A,B两个用户读同一数据并进行修改,其中一个用户的修改结果破坏了另一个修改的结果,比如订票...

东风125 ⋅ 2015/11/22 ⋅ 0

数据库常见死锁原因及处理

数据库是一个多用户使用的共享资源,当多个用户并发地存取数据时,在数据库中就会产生多个事务同时存取同一数据的情况。若对并发操作不加控制就可能会读取和存储不正确的数据,破坏数据库的一...

登录404 ⋅ 2017/07/11 ⋅ 2

事务并发的可能问题与其解决方案

一、多个事务并发时可能遇到的问题 Lost Update 更新丢失 a. 第一类更新丢失,回滚覆盖:撤消一个事务时,在该事务内的写操作要回滚,把其它已提交的事务写入的数据覆盖了。b. 第二类更新丢失...

傅易 ⋅ 2016/11/20 ⋅ 0

深入理解乐观锁与悲观锁

在数据库的锁机制中介绍过,数据库管理系统(DBMS)中的并发控制的任务是确保在多个事务同时存取数据库中同一数据时不破坏事务的隔离性和统一性以及数据库的统一性。 乐观并发控制(乐观锁)和...

Hosee ⋅ 2016/06/01 ⋅ 0

mysql数据库死锁的产生原因及解决办法

数据库和操作系统一样,是一个多用户使用的共享资源。当多个用户并发地存取数据 时,在数据库中就会产生多个事务同时存取同一数据的情况。若对并发操作不加控制就可能会读取和存储不正确的数...

阿泽Aze ⋅ 03/30 ⋅ 0

深入理解乐观锁与悲观锁

在数据库的锁机制中介绍过,数据库管理系统(DBMS)中的并发控制的任务是确保在多个事务同时存取数据库中同一数据时不破坏事务的隔离性和统一性以及数据库的统一性。 乐观并发控制(乐观锁)和...

LYQ1990 ⋅ 2016/04/29 ⋅ 0

SQL Server 中的锁与并发

原文出处:nogos 并发可以定义为多个进程同时访问或修改共享数据的能力。处于活动状态而互不干涉的并发用户进程的数量越多,数据库系统的并发性就越好。当一个正在修改数据的进程阻止了其他进...

nogos ⋅ 2016/08/10 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

Spring发展历程总结

转自与 https://www.cnblogs.com/RunForLove/p/4641672.html 目前很多公司的架构,从Struts2迁移到了SpringMVC。你有想过为什么不使用Servlet+JSP来构建Java web项目,而是采用SpringMVC呢?...

onedotdot ⋅ 36分钟前 ⋅ 0

Python模块/包/库安装(6种方法)

Python模块/包/库安装(6种方法) 冰颖机器人 2016-11-29 21:33:26 一、方法1: 单文件模块 直接把文件拷贝到 $python_dir/Lib 二、方法2: 多文件模块,带setup.py 下载模块包(压缩文件zip...

cswangyx ⋅ 55分钟前 ⋅ 0

零基础学习大数据人工智能,学习路线篇!系统规划大数据之路?

大数据处理技术怎么学习呢?首先我们要学习Python语言和Linux操作系统,这两个是学习大数据的基础,学习的顺序不分前后。 Python:Python 的排名从去年开始就借助人工智能持续上升,现在它已经...

董黎明 ⋅ 今天 ⋅ 0

openJdk和sun jdk的区别

使用过LINUX的人都应该知道,在大多数LINUX发行版本里,内置或者通过软件源安装JDK的话,都是安装的OpenJDK, 那么到底什么是OpenJDK,它与SUN JDK有什么关系和区别呢? 历史上的原因是,Ope...

jason_kiss ⋅ 今天 ⋅ 0

梳理

Redux 是 JavaScript 状态容器,提供可预测化的状态管理。 它是JS的状态容器,是一种解决问题的方式,所以即可以用于 react 也可以用于 vue。 需要理解其思想及实现方式。 应用中所有的 stat...

分秒 ⋅ 今天 ⋅ 0

Java 后台判断是否为ajax请求

/** * 是否是Ajax请求 * @param request * @return */public static boolean isAjax(ServletRequest request){return "XMLHttpRequest".equalsIgnoreCase(((HttpServletReques......

JavaSon712 ⋅ 今天 ⋅ 0

Redis 单线程 为何却需要事务处理并发问题

Redis是单线程处理,也就是命令会顺序执行。那么为什么会存在并发问题呢? 个人理解是,虽然redis是单线程,但是可以同时有多个客户端访问,每个客户端会有 一个线程。客户端访问之间存在竞争...

码代码的小司机 ⋅ 今天 ⋅ 0

到底会改名吗?微软GVFS 改名之争

微软去年透露了 Git Virtual File System(GVFS)项目,GVFS 是 Git 版本控制系统的一个开源插件,允许 Git 处理 TB 规模的代码库,比如 270 GB 的 Windows 代码库。该项目公布之初就引发了争...

linux-tao ⋅ 今天 ⋅ 0

笔试题之Java基础部分【简】【二】

1.静态变量和实例变量的区别 在语法定义上的区别:静态变量前要加static关键字,而实例变量前则不加。在程序运行时的区别:实例变量属于某个对象的属性,必须创建了实例对象,其中的实例变...

anlve ⋅ 今天 ⋅ 0

Lombok简单介绍及使用

官网 通过简单注解来精简代码达到消除冗长代码的目的 优点 提高编程效率 使代码更简洁 消除冗长代码 避免修改字段名字时忘记修改方法名 4.idea中安装lombnok pom.xml引入 <dependency> <grou...

to_ln ⋅ 今天 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部