mysql中的锁机制之悲观锁和乐观锁

1、悲观锁?

悲观锁顾名思义就是很悲观,悲观锁认为数据随时就有可能会被外界进行修改,所以悲观锁一上来就会把数据给加上锁。悲观锁一般都是依靠关系型数据库提供的锁机制,然而事实上关系型数据库中的行锁,表锁不论是读写锁都是悲观锁。

2、乐观锁?

乐观锁顾名思义,就是很乐观,每次自己操作数据的时候认为没有人会来修改它,所以不会去对数据进行加锁。但是在更新的时候会去判断在此期间数据有没有被修改,需要用户自己去实现乐观锁。乐观锁不会发生并发抢占资源,只有在提交操作的时候检查是否违反数据完整性。

2.1、为什么要使用乐观锁呢?

①、对于读操作远多于写操作的时候,大多数都是读取,这时候一个更新操作加锁会阻塞所有读取,降低了吞吐量

②、最后还要释放锁,锁是需要一些开销的,我们只要想办法解决极少量的更新操作的同步问题

③、换句话说,如果读写比例差距不是非常大或者你的系统没有响应不及时,吞吐量瓶颈问题,那就不要去使用乐观锁,它增加了复杂度,也带来了额外的风险

2.2、乐观锁的实现方式

前期准备工作(准备数据表和测试数据):

CREATE TABLE `employee`  (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(20) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
  `dep_id` int(11) NULL DEFAULT NULL,
  `age` int(11) NULL DEFAULT NULL,
  `salary` decimal(10, 2) NULL DEFAULT NULL,
  `cus_id` int(11) NULL DEFAULT NULL,
  `version` int(11) NULL DEFAULT NULL COMMENT ‘用来给乐观锁进行标识的字段‘,
  PRIMARY KEY (`id`) USING BTREE,
  INDEX `idx_name_age`(`name`, `age`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 109 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;

-- 插入测试数据
INSERT INTO `employee` VALUES (1, ‘李白‘, 1, 10, 1000.00, 1, 1);
INSERT INTO `employee` VALUES (2, ‘韩信‘, 1, 20, 2000.00, 1, 1);
INSERT INTO `employee` VALUES (3, ‘露娜‘, 1, 20, 2500.00, 1, 1);
INSERT INTO `employee` VALUES (4, ‘公孙离‘, 4, 20, 3000.00, 1, 1);
INSERT INTO `employee` VALUES (5, ‘虞姬‘, 4, 40, 3500.00, 2, 1);
INSERT INTO `employee` VALUES (6, ‘孙尚香‘, 6, 20, 5000.00, 1, 1);
INSERT INTO `employee` VALUES (7, ‘马可波罗‘, 6, 50, 5000.00, 1, 1);
INSERT INTO `employee` VALUES (8, ‘后羿‘, 30, 35, 4000.00, 1, 1);

2.2.1、版本号的实现方式:

①、就是给数据增加一个版本标识,在数据表上增加一个version字段

②、每次更新把这个字段加1

③、读取数据的时候把version读出来,更新的时候比较version

④、如果还是开始读取的version就可以更新了

⑤、如果现在的version比老的version大,说明有其他事务更新了该数据,并增加了版本号

⑥、这时候得到一个无法更新的通知,用户自行根据这个通知来决定怎么处理,比如重新开始一遍

版本号的方式实现乐观锁示例:

-- 先获取version字段的值,这里version字段的值目前是:1
SELECT version FROM employee WHERE id = 1;

-- 更新该条数据的时候做数据验证,更新成功后将version字段的值累加1,更新条件除了id还要加上version=上面取出来的值 才能进行更新
UPDATE employee SET `name` = ‘李白大魔王‘,version = version + 1 WHERE id = 1 AND version = 1;

示例截图:

2.2.2、时间戳的实现方式:

①、和上面的版本号基本一样,只是通过时间戳来判断而已,注意时间戳要使用数据库服务器的时间戳不能是业务系统的时间

②、同样是在需要乐观锁控制的table(表)中增加一个字段,字段名称无所谓

③、字段类型使用时间戳, 和上面的version类似,也是在更新提交的时候检查当前数据库中数据的时间戳和自己更新前取到的时间戳进行对比

④、如果一致则OK 执行更新操作,否则就是版本冲突

原文地址:https://www.cnblogs.com/candii/p/11823858.html

时间: 2024-07-29 14:50:10

mysql中的锁机制之悲观锁和乐观锁的相关文章

[数据库事务与锁]详解七: 深入理解乐观锁与悲观锁

注明: 本文转载自http://www.hollischuang.com/archives/934 在数据库的锁机制中介绍过,数据库管理系统(DBMS)中的并发控制的任务是确保在多个事务同时存取数据库中同一数据时不破坏事务的隔离性和统一性以及数据库的统一性. 乐观并发控制(乐观锁)和悲观并发控制(悲观锁)是并发控制主要采用的技术手段. 无论是悲观锁还是乐观锁,都是人们定义出来的概念,可以认为是一种思想.其实不仅仅是关系型数据库系统中有乐观锁和悲观锁的概念,像memcache.hibernate.

大话Linux内核中锁机制之RCU、大内核锁

大话Linux内核中锁机制之RCU.大内核锁 在上篇博文中笔者分析了关于完成量和互斥量的使用以及一些经典的问题,下面笔者将在本篇博文中重点分析有关RCU机制的相关内容以及介绍目前已被淘汰出内核的大内核锁(BKL).文章的最后对<大话Linux内核中锁机制>系列博文进行了总结,并提出关于目前Linux内核中提供的锁机制的一些基本使用观点. 十.RCU机制 本节将讨论另一种重要锁机制:RCU锁机制.首先我们从概念上理解下什么叫RCU,其中读(Read):读者不需要获得任何锁就可访问RCU保护的临界

(转)SQL SERVER的锁机制(一)——概述(锁的种类与范围)

锁定:通俗的讲就是加锁.锁定是 Microsoft SQL Server 数据库引擎用来同步多个用户同时对同一个数据块的访问的一种机制. 定义:当有事务操作时,数据库引擎会要求不同类型的锁定,如相关数据行.数据页或是整个数据表,当锁定运行时,会阻止其他事务对已经锁定的数据行.数据页或数据表进行操作.只有在当前事务对于自己锁定的资源不在需要时,才会释放其锁定的资源,供其他事务使用. 一.锁的种类与范围(如下表) 锁类型 说明 共享 (S) 用于不更改或不更新数据的读取操作,如 SELECT 语句.

SQL SERVER的锁机制(一)——概述(锁的种类与范围)

锁定:通俗的讲就是加锁.锁定是 Microsoft SQL Server 数据库引擎用来同步多个用户同时对同一个数据块的访问的一种机制. 定义:当有事务操作时,数据库引擎会要求不同类型的锁定,如相关数据行.数据页或是整个数据表,当锁定运行时,会阻止其他事务对已经锁定的数据行.数据页或数据表进行操作.只有在当前事务对于自己锁定的资源不在需要时,才会释放其锁定的资源,供其他事务使用. 一.锁的种类与范围(如下表) 锁类型 说明 共享 (S) 用于不更改或不更新数据的读取操作,如 SELECT 语句.

(转)SQL SERVER的锁机制(二)——概述(锁的兼容性与可以锁定的资源)

二.完整的锁兼容性矩阵(见下图) 对上图的是代码说明:见下图. 三.下表列出了数据库引擎可以锁定的资源. 名称 资源 缩写 编码 呈现锁定时,描述该资源的方式 说明 数据行 RID RID 9 文件编号:分页编号:Slot编号 用于锁定堆中的单个行的行标识符. 索引键 KEY KEY 7 6字节哈希值 索引中用于保护可序列化事务中的键范围的行锁. 分页 PAGE PAG 6 文件编号:分页编号 数据库中的 8 KB 页,例如数据页或索引页. 范围 EXTENT EXT 8 文件编号:范围的第一个

(转)SQL SERVER的锁机制(三)——概述(锁与事务隔离级别)

五.锁与事务隔离级别 事务隔离级别简单的说,就是当激活事务时,控制事务内因SQL语句产生的锁定需要保留多入,影响范围多大,以防止多人访问时,在事务内发生数据查询的错误.设置事务隔离级别将影响整条连接. SQL Server 数据库引擎支持所有这些隔离级别: · 未提交读(隔离事务的最低级别,只能保证不读取物理上损坏的数据) · 已提交读(数据库引擎的默认级别) · 可重复读 · 可序列化(隔离事务的最高级别,事务之间完全隔离) SQL Server 还支持使用行版本控制的两个事务隔离级别.一个是

SQL SERVER的锁机制(二)——概述(锁的兼容性与可以锁定的资源)

二.完整的锁兼容性矩阵(见下图) 对上图的是代码说明:见下图. 三.下表列出了数据库引擎可以锁定的资源. 名称 资源 缩写 编码 呈现锁定时,描述该资源的方式 说明 数据行 RID RID 9 文件编号:分页编号:Slot编号 用于锁定堆中的单个行的行标识符. 索引键 KEY KEY 7 6字节哈希值 索引中用于保护可序列化事务中的键范围的行锁. 分页 PAGE PAG 6 文件编号:分页编号 数据库中的 8 KB 页,例如数据页或索引页. 范围 EXTENT EXT 8 文件编号:范围的第一个

面试官问:请介绍一下MySQL数据库的锁机制?

为什么要加锁 问题背景 当多个用户并发地存取数据时,在数据库中就会产生多个事务同时存取同一数据的情况.若对并发操作不加控制就可能会读取和存储不正确的数据,破坏数据库的一致性. 要解决的问题 多用户环境下保证数据库完整性和一致性 锁是什么 在计算机科学中,锁是在执行多线程时用于强行限制资源访问的同步机制,即用于在并发控制中保证对互斥要求的满足. 加锁是实现数据库并发控制的一个非常重要的技术.当事务在对某个数据对象进行操作前,先向系统发出请求,对其加锁.加锁后事务就对该数据对象有了一定的控制,在该事

深入理解乐观锁与悲观锁

在数据库的锁机制中介绍过,数据库管理系统(DBMS)中的并发控制的任务是确保在多个事务同时存取数据库中同一数据时不破坏事务的隔离性和统一性以及数据库的统一性. 乐观并发控制(乐观锁)和悲观并发控制(悲观锁)是并发控制主要采用的技术手段. 无论是悲观锁还是乐观锁,都是人们定义出来的概念,可以认为是一种思想.其实不仅仅是数据库系统中有乐观锁和悲观锁的概念,像memcache.hibernate.tair等都有类似的概念. 针对于不同的业务场景,应该选用不同的并发控制方式.所以,不要把乐观并发控制和悲