数据库 之 锁的概念和显示锁的使用

1  概述

【为什么要锁】

当并发事务同时访问一个资源时,有可能导致数据不一致,因此需要一种机制来将数据访问顺序化,以保证数据库数据的一致性。锁就是其中的一种机制。

数据库是一个多用户使用的共享资源,比如一个用户表t_user,两个浏览器前面的人登录了同个一个账号,把电话号码改了。当多个用户并发地存取数据时,在数据库中就会产生多个事务同时存取同一数据的情况。若对并发操作不加控制就可能会读取和存储不正确的数据,破坏数据库的一致性(脏读,不可重复读,幻读等),可能产生死锁。为了解决这个问题,加锁是一个非常重要的技术,对实现数据库并发控制是一个好的方案。简单说,当一个执行sql语句的事务想要操作表记录之前,先向数据库发出请求,对你访问的记录集加锁,在这个事务释放这个锁之前,其他事务不能对这些数据进行更新操作。

数据库管理系统(DBMS)中的并发控制的任务是确保在多个事务同时存取数据库中同一数据时不破坏事务的隔离性和统一性以及数据库的统一性。下面举例说明并发操作带来的数据不一致性问题:

现有两处火车票售票点,同时读取某一趟列车车票数据库中车票余额为 X。两处售票点同时卖出一张车票,同时修改余额为 X -1写回数据库,这样就造成了实际卖出两张火车票而数据库中的记录却只少了一张。 产生这种情况的原因是因为两个事务读入同一数据并同时修改,其中一个事务提交的结果破坏了另一个事务提交的结果,导致其数据的修改被丢失,破坏了事务的隔离性。并发控制要解决的就是这类问题。

封锁、时间戳、乐观并发控制(乐观锁)和悲观并发控制(悲观锁)是并发控制主要采用的技术手段。

2  概念介绍

锁类型 :

读锁:共享锁,可被多个读操作共享;只能共享给读。

写锁:排它锁,独占锁;

锁粒度:

表锁:在表级别施加锁,并发性较低;表级锁的粒度大于行级锁

行锁:在行级别施加锁,并发性较高;维持锁状态的成本较大;

锁的粒度越小,可能会造成死锁的状态。如两行需要同时编辑的时候,互相需要等待另一行解锁,造成了死锁的情况。

锁策略:在锁粒度及数据安全性之间寻求一种平衡机制;使得并发机制正常,同时又能维持正常的锁状态。

存储引擎级别的锁:级别以及何时施加或释放锁由存储引擎自行决定;由引擎决定

MySQL Server:表级别,可自行决定,也允许显式请求;允许用户手动请求和施加锁,是表级别的。

锁类别:

显式锁:用户手动请求的锁;

隐式锁:存储引擎自行根据需要施加的锁;

3  显式锁的使用

(1) LOCK TABLES

LOCK TABLES  tbl_name  read|write, tbl_name read|write, ...

UNLOCK TABLES #解开全部的锁,后面不跟表名

施加写锁,写锁是排他的,不允许别的线程读和写,自己施加锁是不受影响

lock tables classlist write;

MariaDB [sunny]> lock tables classlist write;

Query OK, 0 rows affected (0.00 sec)

MariaDB [sunny]> select * from classlist; #此时是可以正常读写

Empty set (0.00 sec)

注意,此时当另一用户连接的时候(从另一终端登录该数据库),查看的时候,结果就出不来,处于锁住的状态。

MariaDB [sunny]> select * from classlist;

施加读锁后,别的进程可以看,但是不能插入数据,读锁对写锁排斥,解锁后才能正常

MariaDB [sunny]> lock tables classlist read;

Query OK, 0 rows affected (0.00 sec)

此时从另一终端登录插入数据时是处于锁住状态

MariaDB [sunny]> insert into classlist values ("sunny",1,"100");

(2) FLUSH TABLES:将内存中的数据同步到磁盘上,即刷写操作,但是这个同步过程可以施加锁,一旦施加锁的时候,即执行将对应的表同步,关闭,打开,并施加锁。一旦施加了锁,此时别的线程读操作不受影响,但是写操作将不能被执行,需要解锁后才能生效

FLUSH TABLES tbl_name,... [WITH READ LOCK];

UNLOCK TABLES;

锁住所有的表,注意,可以针对某张表进行上锁

MariaDB [sunny]> flush tables with read lock;

Query OK, 0 rows affected (0.00 sec)

其他线程,解锁后才能够插入数据

MariaDB [sunny]> insert into classlist values ("tracy",2,"99");

Query OK, 1 row affected (1 min 5.58 sec)

(3) SELECT cluase #FOR UPDATE请求施加写锁,LOCK IN SHARE MODE施加读锁,一般不操作

[FOR UPDATE | LOCK IN SHARE MODE]

一般要操作的是手动解锁。但是可能会对已经在软件层的操作造成影响。

更多介绍建议参考链接:

数据库的锁机制:http://blog.csdn.net/lexang1/article/details/52248686

数据库为什么需要锁机制?有哪些锁机制?:https://www.cnblogs.com/fanp/p/4633453.html

原文地址:http://blog.51cto.com/ghbsunny/2060567

时间: 2024-10-04 13:43:20

数据库 之 锁的概念和显示锁的使用的相关文章

显示锁和aqs

一.内置锁sync 和 显示锁lock概念 1.synv锁又叫内置锁,不能中断,拿不到无限等待即阻塞: java自带关键字: 隐式可重入: 重入锁:锁对应对象要多次调用对应方法,如递归 2. lock的lockinterruptiply意思是可中断的:语言层面的接口: 其实现类reentrantlock 可重入锁,sync锁显示对应,可以理解为sync关键字在lock接口下的实现: 3.重入锁:锁对应对象要多次调用对应方法,如递归: 可重入锁,sync内置锁,多次获取和释放,计数器加1减1,方法

第十三章 显示锁

Java 5.0 提供的新的加锁机制:当内置加锁机制不适合时 , 作为一种可选择的高级功能 一个可重入的互斥锁 Lock,它具有与使用 synchronized 方法和语句所访问的隐式监视器锁相同的一些基本行为和语义,但功能更强大. 13.1 Lock 与 ReentrantLock Lock 中实现的必须提供与内置锁相同的内存可见 性语义, 但在加锁语义,调度算法,顺序保证和性能特性方面有所不同. 13.1.1 轮询锁和定时锁 在内置锁中, 解决死锁的唯一方法是 重新启动程序. 防止死锁的唯一

乐观锁,悲观锁,表锁,行锁,共享锁,排他锁

乐观锁 乐观锁是指操作数据库时(更新操作),想法很乐观,认为这次的操作不会导致冲突,在操作数据时,并不进行任何其他的特殊处理(也就是不加锁),而在进行更新后,再去判断是否有冲突了. 实现方式1:在表中的数据进行操作时(更新),先给数据表加一个版本(version)字段,每操作一次,将那条记录的版本号加1.也就是先查询出那条记录,获取出version字段,如果要对那条记录进行操作(更新),则先判断此刻version的值是否与刚刚查询出来时的version的值相等,如果相等,则说明这段期间,没有其他

数据库中乐观锁与悲观锁的概念

锁( locking ) 业务逻辑的实现过程中,往往需要保证数据访问的排他性.如在金融系统的日终结算 处理中,我们希望针对某个 cut-off 时间点的数据进行处理,而不希望在结算进行过程中 (可能是几秒种,也可能是几个小时),数据再发生变化.此时,我们就需要通过一些机 制来保证这些数据在某个操作过程中不会被外界修改,这样的机制,在这里,也就是所谓 的 " 锁 " ,即给我们选定的目标数据上锁,使其无法被其他程序修改. Hibernate 支持两种锁机制:即通常所说的 " 悲

今天初步了解了informix的锁的概念

今天初步了解了informix的锁的概念 2005-06-12 01:07:05 分类: IT生活 在load的时候,碰到好几次"-134 ISAM Error :no more locks",原来是数据库中的锁的数量不够所致,后来到/informix/etc/下修改onconfig文件,把LOCKS的值增加到20000(原来400),问题解决. 但在网上还看到有人用事务独占的方式,没试过.原文是这样的:建议先打开事务处理begin work;然后使用lock table tablen

MySQL数据库引擎、事务隔离级别、锁

MySQL数据库引擎.事务隔离级别.锁 数据库引擎InnoDB和MyISAM有什么区别 大体区别为: MyISAM类型不支持事务处理等高级处理,而InnoDB类型支持.MyISAM类型的表强调的是性能,其执行效率比InnoDB类型更快,但是不支持事务,而InnoDB提供事务支持以及外键等高级数据库功能. 具体实现的区别: InnoDB不支持FULLTEXT类型的索引 InnoDB中不保存表的具体行数,也就是说,执行查询SQL时,InnoDB要扫描一遍整个表来计算有多少行,而MyISAM只要简单的

java中锁的概念/介绍

前言 Java提供了种类丰富的锁,每种锁因其特性的不同,在适当的场景下能够展现出非常高的效率.本文旨在对锁相关源码(本文中的源码来自JDK 8和Netty 3.10.6).使用场景进行举例,为读者介绍主流锁的知识点,以及不同的锁的适用场景. Java中往往是按照是否含有某一特性来定义锁,我们通过特性将锁进行分组归类,再使用对比的方式进行介绍,帮助大家更快捷的理解相关知识.下面给出本文内容的总体分类目录: ? 1. 乐观锁 VS 悲观锁 乐观锁与悲观锁是一种广义上的概念,体现了看待线程同步的不同角

转载 sqlserver 锁的概念

SQL server共享锁,排他锁,更新锁的使用   上一篇 / 下一篇  2009-11-08 00:29:17 / 个人分类:数据库 查看( 889 ) / 评论( 0 ) / 评分( 0 / 0 ) 锁的概述 一. 为什么要引入锁 多个用户同时对数据库的并发操作时会带来以下数据不一致的问题: 丢失更新 A,B两个用户读同一数据并进行修改,其中一个用户的修改结果破坏了另一个修改的结果,比如订票系统 脏读 A用户修改了数据,随后B用户又读出该数据,但A用户因为某些原因取消了对数据的修改,数据恢

Java并发(基础知识)——显示锁和同步工具类

显示锁                                                                                     Lock接口是Java 5.0新增的接口,该接口的定义如下: public interface Lock { void lock(); void lockInterruptibly() throws InterruptedException; boolean tryLock(); boolean tryLock(long