MySQL事务和锁实战篇
MySQL事务和锁
事务
说到关系型的数据库的事务,相信大家对四大特性都不陌生,分别是原子性、一致性、隔离性、持久性,简称为ACID特性。
MySQL中支持3种不同的存储引擎:
MyISAM存储引擎、Memory存储引擎、和InnoDB存储引擎
注:只有InnoDB才支持事务。
事务的控制语句
| 控制语句 | 作用 |
|---|---|
| begin或者start transaction | 开启一个事务 |
| commit 或者 commit work | 提交事务,进行持久性修改 |
| rollback 或者 rollback work | 回滚事务,撤销已经进行修改但未提交的操作 |
| savepoint [保存点] | 在事务中创建一个保存点,一个事务可以有多个保存点 |
| releasavepoint [保存点] | 回滚到指定的保存点 |
| set transaction | 设置事务的隔离级别 |
事务隔离级别设置
先复习一个事务的四大隔离级别
读未提交(READ-UNCOMMITTED)
读已提交(READ-COMMITTED)
可重复读(RE-PEATABLE-READ)
可序列化读(SERIALIZABLE)
下面是操作过程。
首先,查看默认的事务隔离级别,可以看到是可重复读(REPEATABLE-READ),
show variables like '%isolation%';
脏读
我们来演示一下脏读的场景,下面这张图是展示了我原先已经创建好的两个用户的账号都为100元。

分别打开两个连接mysql的会话窗口,其中一个会话的隔离级别为READ-UNCOMMITED,然后再另一个窗口中开启一个事务,例如,lisi给zhangsan转账100元,
set session transaction isolation level read uncommitted;
begin;
update user set money=money-100 where user=lisi;
我们在另外一个读未提交的窗口中查看,zhangsan看到钱已经转过来了,但是实际上lisi的事务还没有提交,假如这个时候,lisi不想转账了,回滚事务,那zhangsan就读到脏数据了。

不可重复读
下面来展示一下不可重复读的场景。
首先我们将zhangsan的窗口的事务隔离级别设置成READ-COMMITTED,并且在两个窗口都开启事务
set session transaction isolation level read committed;
假设zhangsan现在想统计全部人的钱有多少,很明显200;

但是这个时候lisi往账户里面存了100元,并提交事务,但是这个时候,zhangsan再次查询总和,我们会查询到总金额为300,但是这次查询是处于同一个事务中,查询到两次不一样的结果,属于不可重复读的情况。
update user set money=money+100 where user='lisi';
commit;

幻读
为了解决不可重复读的问题,我们将事务的隔离等级设置成RE-PEATABLE-READ,即MySQL默认的事务隔离等级,然后在两边都开启一个事务。
set session transaction isolation level repeatable read;
我们先在一个窗口插入一条数据并提交,然后在另外一个窗口查看,此时是查询不到这个记录的,但是假如这个时候我们新插入一条主键和刚插入的记录一样的话,我们就可以发现
insert into user values('zly1',100);
# 另外一个窗口
insert into user values('zly1',100);
ERROR 1062 (23000): Duplicate entry 'zly1' for key 'user.PRIMARY'
这样也算是一种幻读的现象,但是网上也有一种说法在可重复读的等级下,幻读是可避免的,这种说法不是非常准确的,如果在进行更新和插入时就可能会出现幻读的情况,如果想要解决幻读的情况,可以将事务隔离等级设置到SERIALIZABLE
锁机制
InnoDB的行级锁
InnoDB默认采用的行级锁,分为以下这两种,分别为共享锁和排他锁。
这两个概念我在这篇文章中也有介绍。
共享锁(S锁):也叫读锁,如果在该数据对象上加了共享锁,该事务可以读取但是不能修改数据。其他事务也可以在该对象上加共享锁,但是不能修改数据。
排他锁(X锁):也叫写锁,在一个数据对象只有一把排他锁,获取到该锁的事务可以读取数据和修改数据。
(加锁:一般的查询语句不会加任何的锁类型,当然也可以为数据加锁,比如在select * from … for update,这样可以为数据添加排他锁,而使用select … lock in share mode 可以为数据添加共享锁。
锁实战
首先关闭事务自动提交
set autocommit=0;
我们先在一个窗口输入一条获取到排他锁,虽然操作的是一条数据,但是锁的是整张表,因为我们没有添加索引。
select * from user where user='zly1' for update;


这个时候我们对user这一列添加索引,就可以看到我们对其进行加锁就不会出现阻塞的情况了。
alter table user add index(user);


注:在MySQL的行级锁是针对索引加的锁,而不是针对表中的行加级锁,虽然访问不同行的记录,但是如果不存在对应的索引,或者使用相同的索引的话,就会造成锁的冲突而锁住整张表。
死锁
死锁是指两个或者两个以上的额事务在执行过程中,因为互相的等待或者因为争抢相同的资源而造成的互相等待现象。
我们还是采用刚刚的例子,还是将事务的自动提交关闭掉,首先先在会话1中,更新id为1的记录,然后在会话2中更新id为2的记录,这个时候我们再回来在会话1更新id为2的记录,在会话2中更新id为1的记录,就会产生一个死锁;


总结
本文主要介绍了事务的隔离等级和事务的锁机制,主要更加偏向于实战部分,我前面也有一些文章涉及到。
MySQL事务和锁实战篇的更多相关文章
- MySQL 5.7主从复制实战篇
MySQL 5.7主从复制实战篇 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.安装MySQL数据库并启动 1>.在MySQL官方下载相应的安装包(https://dev ...
- MySQL事务与锁
MySQL事务与锁 锁的基本概念 锁是计算机协调多个进程或线程并发访问某一资源的机制. 相对其他数据库而言,MySQL的锁机制比较简单,其最显著的特点是不同的存储引擎支持不同的锁机制.比如,MyISA ...
- 关于mysql事务行锁for update实现写锁的功能
关于mysql事务行锁for update实现写锁的功能 读后感:用切面编程的理论来讲,数据库的锁对于业务来说是透明的.spring的事务管理代码,业务逻辑代码,表锁,应该是三个不同的设计层面. 在电 ...
- mysql事务和锁InnoDB
背景 MySQL/InnoDB的加锁分析,一直是一个比较困难的话题.我在工作过程中,经常会有同事咨询这方面的问题.同时,微博上也经常会收到MySQL锁相关的私信,让我帮助解决一些死锁的问题.本文,准备 ...
- mysql事务和锁InnoDB(转)
背景 MySQL/InnoDB的加锁分析,一直是一个比较困难的话题.我在工作过程中,经常会有同事咨询这方面的问题.同时,微博上也经常会收到MySQL锁相关的私信,让我帮助解决一些死锁的问题.本文,准备 ...
- javaweb(三十八)——mysql事务和锁InnoDB(扩展)
MySQL/InnoDB的加锁分析,一直是一个比较困难的话题.我在工作过程中,经常会有同事咨询这方面的问题.同时,微博上也经常会收到MySQL锁相关的私信,让我帮助解决一些死锁的问题.本文,准备就My ...
- 面试官一口气问了MySQL事务、锁和MVCC,我
面试官:你是怎么理解InnoDB引擎中的事务的? 候选者:在我的理解下,事务可以使「一组操作」要么全部成功,要么全部失败 候选者:事务其目的是为了「保证数据最终的一致性」. 候选者:举个例子,我给你发 ...
- MYSQL事务和锁
mysql事务(一)—转载 2012年12月20日 ⁄ Mysql数据库, 技术交流 ⁄ 暂无评论 一. 什么是事务 事务就是一段sql 语句的批处理,但是这个批处理是一个atom(原子) ,不可分割 ...
- MySQL 事务与锁机制
下表展示了本人安装的MariaDB(10.1.19,MySQL的分支)所支持的所有存储引擎概况,其中支持事务的有InnoDB.SEQUENCE,另外InnoDB还支持XA事务,MyISAM不支持事务. ...
- MySql 事务与锁
事务介绍 首先,什么是事务?事务就是一段sql 语句的批处理,但是这个批处理是一个atom(原子),不可分割,要么都执行,要么回滚(rollback)都不执行. MySQL 事务主要用于处理操作量大, ...
随机推荐
- ARM-linux的Windows交叉编译环境搭建
交叉编译Arm Linux平台的QT5库 1.准备交叉编译环境 环境说明:Windows10 64位 此过程需要: (1)Qt库开源代码,我使用的是5.13.0版本: (2)Perl语言环境5.12版 ...
- easycode模版-基于ruoyi-cloud
##定义初始变量 #set($tableName = $tool.append($tableInfo.name, "Controller")) ##设置回调 $!callback. ...
- 利用网络复制安装额外域控制器、利用介质安装额外域控制器、安装RODC额外域控制器
一.拥有多台域控制器的优势 1.分担用户身份验证的负担,改善用户登录的效率 2.容错功能:若有域控制器故障,此时仍然可以有其他正常的域控制器来继续提供服务,因此对用户的服务并不会停止 二.系统提供两种 ...
- NET 实现 Cron 定时任务执行,告别第三方组件
原文连接: (96条消息) NET 实现 Cron 定时任务执行,告别第三方组件_.net 定时任务_Phil Arist的博客-CSDN博客 代码: using System.Globalizati ...
- java8利用流和lambda表达式对list遍历处理
java8的lambda表达式提供了一些方便list操作的方法,主要涵盖分组.过滤.求和.最值.排序.去重. 优点: (1) 简洁,跟之前的传统写法对比,能少写不少代码; (2) 易并行计算.尤其适用 ...
- ACM需要知道的STL小技巧
天天用stl,但是有一些小技巧如果不知道,偶尔会导致TLE,这里说几个打比赛需要用到的. 主要是大概了解一下其底层原理:https://www.jianshu.com/p/834cc223bb57 就 ...
- InstructPix2Pix: 动动嘴皮子,超越PS
摘要:InstructPix2Pix提出了一种使用文本编辑图像的方法:给定输入图像和编辑指令,告诉模型要做什么,模型将遵循这些指令来编辑图像. 本文分享自华为云社区<InstructPix2Pi ...
- Linux & 标准C语言学习 <DAY11>
一.指针 1.什么是指针 指针是一种特殊的数据类型,使用指针可以定义指针变量,指针变量存储的是整形数据,该数据代表了内存的编号(地址),可以通过这个编号访问到对应的内存 ...
- Django笔记三之使用model对数据库进行增删改查
本篇笔记目录索引如下: model 准备 增 查 删 改 1.model 准备 在上一篇笔记中,我们新建了一个 application,增加了几个model 同步到了数据库,这次我们新建一个名为 bl ...
- P6666 [清华集训2016] 数据交互 题解
## P6666 [清华集训2016] 数据交互 题解 ### 简要题意: n个点的树,m次操作,分别为添加一条路径$(u_i,v_i,w_i)$,和撤消一条路径,每一次操作后求出一条路径使得与这条路 ...