数据库系列(三)之 锁

摘要:
避免数据混淆。在熟悉的商场中,有很多方法来处理库存扣减,其中数据库锁是一种流行的方法。在数据库级别,实现锁可以包括表锁、页锁和行锁。在大多数数据库中,delete、insert和update语句的执行将被锁定。删除和插入通常是行锁。答案是肯定的。相反,它被称为乐观锁。事实上,还使用了数据库中的悲观锁。

锁的意义

     数据库中有很多‘锁’的使用。怎么合理并灵活的应用是一个值得讨论深究的问题。

     锁为何而存在?为了在同一时间内,只能处理一种请求。而避免导致的数据错乱。例如商城中,库存的扣减;金融系统中金钱的转账。

     在耳熟能详的商城中,库存扣减有很多种方法来处理,其中数据库锁是很大众的一种方式。在应用程序中,存在着多个用户同一时间购买商品的可能。这时候就要扣减库存。怎么保证库存扣减的正确性呢?答案就是用锁来做限制。

     例如商品只剩下库存数量为1。这时候商品有多人在抢,那么只能有一个人购买成功。否则扣减过多而导致业务销售的‘售后’问题。

 

乐观锁与悲观锁

悲观锁                                                                                              

     悲观锁是指同时只有一个才能处理锁的内容,其它都需要等待排队。悲观锁是建议在数据库层面。

     在数据库层面,实现锁可以有表锁、页锁、行锁。它们各自有优缺点。

表锁                        

     表锁顾名思义,锁住整张表。

     表锁的特点:开销小,加锁快;不会出现死锁;锁冲突概率高,并发度低。

SqlServer

     sqlsever中加表锁很简单,在select最后加相应的语句即可:

共享锁:SELECT * FROM table WITH (HOLDLOCK)

排他锁:SELECT * FROM table WITH (TABLOCKX)

Postgresql

     使用表锁的格式为:LOCK [ TABLE ] [ ONLY ] name [ * ] [, ...] [ IN lockmode MODE ] [ NOWAIT ]

页锁                        

     页锁一般比较少用。

     页锁的特点:开销、加锁速度、并发度在于表锁与行锁之间;会出现死锁。

行锁                        

     行锁是使用较多的一种。

     行锁的特点:开销大,加锁慢;会出现死锁;锁定粒度小;索冲突概率低,并发度高。

     在大部分的数据库中,执行delete、insert、update语句都会加锁,delete、insert一般都是行锁。update时看是否存在索引为查询条件,如果存在则行锁,不存在则表锁。

Mysql

     在Mysql中,不同的引擎支持的表锁是不同的。最广泛使用的引擎是InnoDB,也是作为各大云厂商的默认使用。InnoDB是支持行锁、表锁。MyISAM引擎支持表锁。BDB引擎支持表锁、页锁。

     这里只介绍InnoDB引擎,这也是使用最多的引擎。

     在mysql中,表锁的语句如下:

共享锁:SELECT * FROM table_name WHERE ... LOCK IN SHARE MODE。

排他锁:SELECT * FROM table_name WHERE ... FOR UPDATE。

     共享锁与排他锁这里不介绍,后面会详细说明。

     表锁没有固定的语句,使用的时候会根据索引来确定使用表锁还是行锁。这意味着:只有通过索引条件检索数据,InnoDB才使用行级锁,否则,InnoDB将使用表锁。

SqlServer

     sqlserver的行级锁比较简单,在表名后面加ROWLOCK即可:

SELECT * FROM table ROWLOCK WHERE id=xxx

Postgresql

     因Json的原因,Postgresql越来越流行。其使用行锁的关键字为:FOR UPDATE、FOR NO KEY UPDATE、FOR SHARE、FOR KEY SHARE。

乐观锁                                                                                               

     在悲观锁中,之所以成为悲观,因为都需要等待的操作。有没有一种无需等待、相互争抢的锁呢?答案是有的,与之相反,称为乐观锁。

     乐观锁不是在数据库层面做的,在程序上写。怎么实现乐观锁呢?通常在表中加个字段,版本号version或当期时间date都可以。

     举个version版本号的例子,例如当期的version=1。

     语句一般为:update table set inventory=1, version=version+1 where version=1 and id=xxx

     这样就实现了乐观锁的模式。因为他们都互相争抢,谁抢到了就返回修改条数为1,没有抢到为0。其实其中也使用到了数据库中的悲观锁。因为在update时,使用了索引,是锁行的。但是这种明显是比全悲观锁的形式是快的。

     乐观锁的特点:速度快、但增加数据库CPU。

 

排它锁与共享锁

     排他锁及共享锁其实很简单。

     排它锁是指在锁住期间,不能对相应的数据做查询、增加、修改、删除操作。排他锁保证了其他事物不能读,用于行级。

     共享锁是指在锁住期间,能对相应的数据做查询操作,不能做增加、修改、删除操作。保证了其他事务不能写,用于表级。

 

可以关注本人的公众号,多年经验的原创文章共享给大家。

数据库系列(三)之 锁第1张

免责声明:文章转载自《数据库系列(三)之 锁》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇ASP.NET Core开发-使用Nancy框架jmeter while循环使用下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

CSS之user-select——设置标签中的文字是否可被复制

  详细介绍请参考 http://www.css88.com/book/css/properties/user-interface/user-select.htm   CSS样式 user-select:none | text | all | element,默认情况下是text,表示标签中的文字可以被复制,none是不可被复制。   为了兼容各种浏览器,...

Oracle数据库三种标准的备份方法

Oracle数据库的三种标准的备份方法: 1.导出/导入(EXP/IMP)。 2.热备份。 3.冷备份。 注释:导出备件是一种逻辑备份,冷备份和热备份是物理备份。 一、导出/导入(Export/Import) 利用Export可将数据从数据库中提取出来,利用Import则可将提取出来的数据送回到Oracle数据库中去。 1、简单导出数据(Export)和导...

Jmeter获取数据库值并作为参数请求(转载)

转载自:https://www.cnblogs.com/mawenqiangios/p/11088672.html 01Jmeter连接数据库 1、添加JDBC Connection Configuration (右键测试计划-->配置元件-->JDBC Connection Configuration) 2、配置数据库连接信息,其中 Data...

教你调用数据库读取短信 记事本 通讯录文件,让ios5的短信恢复到ios4

由于高版本的ios固件向下恢复到低版固件时无法通过itunes恢复备份,所以一些数据,比如SMS需要通过提取文件的方式单独进行备份恢复特别是ios5的短信,之前很是头痛,直接将文件恢复到指定目录修改权限是不行的,因为ios5对sms数据库进行了修改,与ios4不匹配,为了使短信恢复,就尝试打开数据,修改看看,结果证明可行我这里针对的是ios5的短信,当然如...

数据库的几种模式

SQL Server数据库有三种恢复模式:简单恢复模式、完整恢复模式和大容量日志恢复模式: 1.Simple 简单恢复模式, Simple模式的旧称叫”Checkpoint with truncate log“,其实这个名字更形象,在Simple模式下,SQL Server会在每次checkpoint或backup之后自动截断log,也就是丢弃所有的in...

简单演示 Oracle 数据库并发导致段级锁(表级锁)

本文内容 软件环境 简单演示 Oracle 数据库并发导致段级锁(表级锁) 本文简单演示并发导致的行级锁。并发是两个以上的用户对同样的数据进行修改(包括插入、删除和修改)。锁的产生是因为并发。没有并发,就没有锁。并发的产生是因为系统需要,系统需要是因为用户需要。 软件环境 Windows 2003 Server Oracle 11g Rele...