本文实例讲述了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 | × |
× |
× |
四、获取和设置数据库隔离级别
SHOW VARIABLES LIKE '%isolation%'; SHOW GLOBAL VARIABLES LIKE '%isolation%';
使用系统变量查询
SELECT @@GLOBAL.tx_isolation; SELECT @@SESSION.tx_isolation; SELECT @@tx_isolation;
对于mysql8而言,使用下面的变量进行查询
SELECT @@GLOBAL.transaction_isolation; SELECT @@SESSION.transaction_isolation; SELECT @@transaction_isolation;
设置隔离级别
SET GLOBAL tx_isolation = '隔离级别'; SET SESSION tx_isolation = '隔离级别'; SET @@tx_isolation = '隔离级别';
对于mysql8而言,使用下面语句进行设置
SET GLOBAL transaction_isolation = '隔离级别'; SET SESSION transaction_isolation = '隔离级别'; SET @@transaction_isolation = '隔离级别';
五、通过例子说明各隔离级别的情况
先准备一张表,和一点数据。
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、读取未提交
set transaction_isolation = 'READ-UNCOMMITTED'; set autocommit = 0;
事务B修改了表中的数据,但是未提交,事务A确读取到了修改后的数据。如果因为某些原因,事务B回滚了,事务A读取的这个数据就是脏数据。
2、读已提交
set transaction_isolation = 'READ-COMMITTED'; set autocommit = 0;
事务B修改数据但没有提交,那么事务A仍然获取的原来数据,解决了脏读的问题。
但是事务B提交,事务A执行上一次查询,结果与上一次查询不一致,这就产生不可重复读的问题。
3、可重复读取
set transaction_isolation = 'REPEATABLE-READ'; set autocommit = 0;
事务B修改了数据并提交了,事务A两次查询的结果是一致的,解决了不可重复读的问题。
这个时候,事务A去修改name为A的money数据
name为A的money变成了350,而不是400,可重复读保证了数据的一致性。
我们重新在事务A中修改所有账号的money等于200,同时在事务B中插入一条新的数据。
事务A中获取的仍然是两条数据,解决了新增数据时,事务A出现的幻读问题。
4、序列化
set transaction_isolation = 'SERIALIZABLE'; set autocommit = 0;
事务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 锁被释放。
锁表的语句:
LOCK TABLES table_name [READ | WRITE];
解锁表的语句:
UNLOCK TABLES;
锁定数据库中所有表:
FLUSH TABLES WITH READ LOCK;
更多关于MySQL相关内容感兴趣的读者可查看本站专题:《MySQL索引操作技巧汇总》、《MySQL常用函数大汇总》、《MySQL日志操作技巧大全》、《MySQL事务操作技巧汇总》、《MySQL存储过程技巧大全》及《MySQL数据库锁相关技巧汇总》
希望本文所述对大家MySQL数据库计有所帮助。
本文向大家介绍Mysql事务隔离级别原理实例解析,包括了Mysql事务隔离级别原理实例解析的使用技巧和注意事项,需要的朋友参考一下 引言 大家在面试中一定碰到过 说说事务的隔离级别吧? 老实说,事务隔离级别这个问题,无论是校招还是社招,面试官都爱问!然而目前网上很多文章,说句实在话啊,我看了后我都怀疑作者弄懂没!因为他们对可重复读(Repeatable Read)和串行化(serializable
主要内容:事务概述,事务的四大特性,并发事务问题,事务的隔离级别,演示:,总结事务概述 事务是一个或一组sql语句组成的一个执行单元,这个执行单元要么全部执行成功,要么全部执行失败。用于保证数据的完整性。 如账户转账,张三给李四转500,对应的sql语句应该是update张三的 余额-500,并且update李四的余额+500,如果先更新完张三的数据,然后出现了异常,导致李四的余额修改不了,那么就出现数据上的问题了,应该使用事务来解决这一问题,当中间出现异常后回滚,让张三的
本文向大家介绍MySQL查看和修改事务隔离级别的实例讲解,包括了MySQL查看和修改事务隔离级别的实例讲解的使用技巧和注意事项,需要的朋友参考一下 查看事务隔离级别 在 MySQL 中,可以通过show variables like '%tx_isolation%'或select @@tx_isolation;语句来查看当前事务隔离级别。 查看当前事务隔离级别的 SQL 语句和运行结果如下: 结果
本文向大家介绍MySQL的默认事务隔离级别是?相关面试题,主要包含被问及MySQL的默认事务隔离级别是?时的应答技巧和注意事项,需要的朋友参考一下 读未提交(RU): 一个事务还没提交时, 它做的变更就能被别的事务看到. 读提交(RC): 一个事务提交之后, 它做的变更才会被其他事务看到. 可重复读(RR): 一个事务执行过程中看到的数据, 总是跟这个事务在启动时看到的数据是一致的. 当然在可重复
本文向大家介绍MySQL四种事务隔离级别详解,包括了MySQL四种事务隔离级别详解的使用技巧和注意事项,需要的朋友参考一下 本文实验的测试环境:Windows 10+cmd+MySQL5.6.36+InnoDB 一、事务的基本要素(ACID) 1、原子性(Atomicity):事务开始后所有操作,要么全部做完,要么全部不做,不可能停滞在中间环节。事务执行过程中出错,会回滚到事务开始前的状态,所
我已经阅读了大约4个级别的隔离: 我想了解每个事务隔离在表上使用的锁 以下是事务隔离中可能出现的三种现象 脏读取-无锁定 不可重复读取-无脏读取作为对提交数据的锁定 幻影读取-锁定sql块(使用select query选择) 我想了解我们在哪里定义这些隔离级别:仅在jdbc/hibernate级别或在DB中定义 PS:我已经浏览了oracle中隔离级别的链接,但是它们看起来很笨拙,而且只针对数据库