服务器之家:专注于服务器技术及软件下载分享
分类导航

Mysql|Sql Server|Oracle|Redis|MongoDB|PostgreSQL|Sqlite|DB2|mariadb|Access|数据库技术|

服务器之家 - 数据库 - Mysql - mysql的事务,隔离级别和锁用法实例分析

mysql的事务,隔离级别和锁用法实例分析

2021-01-08 15:36怀素真 Mysql

这篇文章主要介绍了mysql的事务,隔离级别和锁用法,结合实例形式分析了MySQL事务,隔离级别和锁相关原理、用法及操作注意事项,需要的朋友可以参考下

本文实例讲述了mysql事务隔离级别用法。分享给大家供大家参考,具体如下:

事务就是一组一起成功或一起失败的sql语句。事务还应该具备,原子性,一致性,隔离性和持久性。

一、事务的基本要素 (acid)

1、原子性:事务开始后,所有的操作,要么全部成功,要么全部失败,不可能处于中间状态,事务是一个不可分割的整体,就像原子一样。

2、一致性:事务开始前和结束后,数据库的完整性约束没有破坏,a向b转账,a扣了钱,但b却没到账。

3、隔离性:同时发生的事务(并发事务)不应该导致数据库处于不一致的状态中,每个事务都独立执行,不影响其他事务的存在。

4、持久性:事务对数据库的更改都会保存在磁盘上,不会丢失。

二、事务的并发问题

1、脏读:事务a读取了事务b未提交的写入数据,读取到的数据就称为脏数据

2、不可重复读:事务a多次读取同一数据,但在读取过程中,事务b对数据做了修改,并提交了。导致多次读取同一数据,结果不一样。

3、幻读:事务a对表中所有数据行进行了修改,比如设置status = 1,但同时,事务b往该表插入了一行新数据status = 0,对于操作事务a的用户而言,表中还有一条记录没被修改,就像发生幻觉一样。

三、事务隔离性的四个级别

事务隔离级别 脏读 不可重复读 幻读
读取未提交 read uncommitted

读已提交 read committed

×

可重复读取 repeatable read

×

×

序列化 serializable

×

×

×

四、获取和设置数据库隔离级别

?
1
2
show variables like '%isolation%';
show global variables like '%isolation%';

使用系统变量查询

?
1
2
3
select @@global.tx_isolation;
select @@session.tx_isolation;
select @@tx_isolation;

对于mysql8而言,使用下面的变量进行查询

?
1
2
3
select @@global.transaction_isolation;
select @@session.transaction_isolation;
select @@transaction_isolation;

设置隔离级别

?
1
2
3
set global tx_isolation = '隔离级别';
set session tx_isolation = '隔离级别';
set @@tx_isolation = '隔离级别';

对于mysql8而言,使用下面语句进行设置

?
1
2
3
set global transaction_isolation = '隔离级别';
set session transaction_isolation = '隔离级别';
set @@transaction_isolation = '隔离级别';

五、通过例子说明各隔离级别的情况

先准备一张表,和一点数据。

?
1
2
3
4
5
6
7
8
9
create table `account` (
 `id` int(11) unsigned not null auto_increment comment 'id',
 `name` varchar(32) default '' comment '名称',
 `money` decimal(11,2) default '0.00' comment '金钱',
 primary key (`id`)
) engine=innodb default charset=utf8mb4;
 
insert into `account` (`name`, `money`) values ('a', '500.00');
insert into `account` (`name`, `money`) values ('b', '100.00');

1、读取未提交

?
1
2
set transaction_isolation = 'read-uncommitted';
set autocommit = 0;

mysql的事务,隔离级别和锁用法实例分析

事务b修改了表中的数据,但是未提交,事务a确读取到了修改后的数据。如果因为某些原因,事务b回滚了,事务a读取的这个数据就是脏数据。

2、读已提交

?
1
2
set transaction_isolation = 'read-committed';
set autocommit = 0;

mysql的事务,隔离级别和锁用法实例分析

事务b修改数据但没有提交,那么事务a仍然获取的原来数据,解决了脏读的问题。

但是事务b提交,事务a执行上一次查询,结果与上一次查询不一致,这就产生不可重复读的问题。

mysql的事务,隔离级别和锁用法实例分析

3、可重复读取

?
1
2
set transaction_isolation = 'repeatable-read';
set autocommit = 0;

mysql的事务,隔离级别和锁用法实例分析

事务b修改了数据并提交了,事务a两次查询的结果是一致的,解决了不可重复读的问题。

这个时候,事务a去修改name为a的money数据

mysql的事务,隔离级别和锁用法实例分析

name为a的money变成了350,而不是400,可重复读保证了数据的一致性。

我们重新在事务a中修改所有账号的money等于200,同时在事务b中插入一条新的数据。

mysql的事务,隔离级别和锁用法实例分析

事务a中获取的仍然是两条数据,解决了新增数据时,事务a出现的幻读问题。

4、序列化

?
1
2
set transaction_isolation = 'serializable';
set autocommit = 0;

mysql的事务,隔离级别和锁用法实例分析

事务a对表进行查询,如果没有提交,则事务b的插入语句一直等待在那里,直到超时或事务a提交。

反之,事务b对表进行插入后,没有提交,则事务a对表的查询也一直等待,直到事务b提交。

此时对表的读写都会进行锁表,当然对并发性能的影响也比较大。

隔离级别越高,越能保证数据的完整性和一致性。

六、mysql的锁

锁分为两种类型:

内部锁:mysql服务器内部执行的内部锁,以管理多个会话对表内容的争用。

外部锁:mysql为客户会话提供显式地获取表锁,以阻止其他会话访问表。

内部锁又会为两种类型:

1、行级锁:行级锁是细粒度的,只有被访问的行会被锁定,这允许多个会话同时进行写访问。

2、表级锁:mysql对myisam,memory和merge表使用表级锁,一次只允许一个会话更新表,这使得这些存储引擎更适用于以读取为主的操作。

外部锁:可以使用 lock table 和 unlock table 来控制锁定。

read (共享锁) :多个会话可以从表中读取数据而不需要获取锁,此外,多个会话可以在同一表上获得锁,当 read 锁时,没有会话可以将数据写入表中。任何写入操作都将处于等待状态,直到 read 锁被释放。

write (排他锁) :当表被 write 锁定时,除持有该锁的会话外,其他会话都不能读取或写入数据,除非 write 锁被释放。

锁表的语句:

?
1
lock tables table_name [read | write];

解锁表的语句:

?
1
unlock tables;

锁定数据库中所有表:

?
1
flush tables with read lock;

希望本文所述对大家MySQL数据库计有所帮助。

原文链接:https://www.cnblogs.com/jkko123/p/10181870.html

延伸 · 阅读

精彩推荐
  • MysqlMySQL 数据备份与还原的示例代码

    MySQL 数据备份与还原的示例代码

    这篇文章主要介绍了MySQL 数据备份与还原的相关知识,本文通过示例代码给大家介绍的非常详细,具有一定的参考借鉴价值,需要的朋友可以参考下...

    逆心2962019-06-23
  • MysqlMySQL锁的知识点总结

    MySQL锁的知识点总结

    在本篇文章里小编给大家整理了关于MySQL锁的知识点总结以及实例内容,需要的朋友们学习下。...

    别人放弃我坚持吖4362020-12-14
  • Mysqlmysql 不能插入中文问题

    mysql 不能插入中文问题

    当向mysql5.5插入中文时,会出现类似错误 ERROR 1366 (HY000): Incorrect string value: '\xD6\xD0\xCE\xC4' for column ...

    MYSQL教程网5722019-11-25
  • Mysql详解MySQL中的分组查询与连接查询语句

    详解MySQL中的分组查询与连接查询语句

    这篇文章主要介绍了MySQL中的分组查询与连接查询语句,同时还介绍了一些统计函数的用法,需要的朋友可以参考下 ...

    GALAXY_ZMY5432020-06-03
  • Mysql浅谈mysql 树形结构表设计与优化

    浅谈mysql 树形结构表设计与优化

    在诸多的管理类,办公类等系统中,树形结构展示随处可见,本文主要介绍了mysql 树形结构表设计与优化,具有一定的参考价值,感兴趣的小伙伴们可以参...

    小码农叔叔5242021-11-16
  • MysqlERROR: Error in Log_event::read_log_event()

    ERROR: Error in Log_event::read_log_event()

    ERROR: Error in Log_event::read_log_event(): read error, data_len: 438, event_type: 2 ...

    MYSQL教程网6402020-03-13
  • MysqlMySQL数据库varchar的限制规则说明

    MySQL数据库varchar的限制规则说明

    本文我们主要介绍了MySQL数据库中varchar的限制规则,并以一个实际的例子对限制规则进行了说明,希望能够对您有所帮助。 ...

    mysql技术网4192019-11-23
  • Mysql解决MySQl查询不区分大小写的方法讲解

    解决MySQl查询不区分大小写的方法讲解

    今天小编就为大家分享一篇关于解决MySQl查询不区分大小写的方法讲解,小编觉得内容挺不错的,现在分享给大家,具有很好的参考价值,需要的朋友一起...

    Veir_dev5592019-06-25