MySQL Transaction--RR事务隔离级别下加锁测试

==============================================================================

按照非索引列更新

在可重复读的事务隔离级别下,在非索引列上进行更新和删除会对所有数据行进行加锁,阻止其他会话对边进行任何数据的增删改操作。

如果更新或删除条件为c3=4且c3列上没有索引则:
1、不允许其他会话插入任意记录,因为所有记录的主键索引上存在X排他锁,无法申请插入意向X锁(lock_mode X insert intention waiting Record lock)
2、不允许其他会话删除任意记录,因为所有记录的主键索引上存在X排他锁
3、不允许其他会话更新任意记录。因为所有记录的主键索引上存在X排他锁

##=========================================##
测试数据:
CREATE TABLE `tb4001` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT,
  `c1` int(11) DEFAULT NULL,
  `c2` varchar(200) DEFAULT NULL,
  `c3` int(11) DEFAULT NULL,
  PRIMARY KEY (`id`),
  KEY `idx_c1` (`c1`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;

insert into tb4001(c1,c2,c3) values(2,2,2);
insert into tb4001(c1,c2,c3) values(4,4,4);
insert into tb4001(c1,c2,c3) values(7,7,7);
insert into tb4001(c1,c2,c3) values(8,8,8);

##=========================================##
##测试1:在没有索引的列上更新
##事务隔离级别:RR
会话1:
SET SESSION tx_isolation=‘REPEATABLE-READ‘;
START TRANSACTION;
SELECT @@GLOBAL.tx_isolation, @@SESSION.tx_isolation;
update tb4001 set c2=777 where c3=7;

##=========================================##
会话2:
SET SESSION tx_isolation=‘REPEATABLE-READ‘;
START TRANSACTION;
SELECT @@GLOBAL.tx_isolation, @@SESSION.tx_isolation;

insert into tb4001(c1,c2,c3) values(9,9,9);

##执行结果:会话2被阻塞
使用SHOW ENGINE INNODB STATUS \G查看阻塞发生时的锁信息
------- TRX HAS BEEN WAITING 13 SEC FOR THIS LOCK TO BE GRANTED:
RECORD LOCKS space id 75 page no 3 n bits 80 index PRIMARY of table `test1`.`tb4001` trx id 10573 lock_mode X insert intention waiting Record lock, heap no 1 PHYSICAL RECORD: n_fields 1; compact format; info bits 0
 0: len 8; hex 73757072656d756d; asc supremum;;

------------------
---TRANSACTION 10571, ACTIVE 404 sec
2 lock struct(s), heap size 1136, 5 row lock(s), undo log entries 1
MySQL thread id 52, OS thread handle 140674621650688, query id 1201 127.0.0.1 admin

##=========================================##
会话2:
SET SESSION tx_isolation=‘REPEATABLE-READ‘;
START TRANSACTION;
SELECT @@GLOBAL.tx_isolation, @@SESSION.tx_isolation;

update tb4001 set c2=888 where c3=8;

##执行结果:会话2被阻塞
使用SHOW ENGINE INNODB STATUS \G查看阻塞发生时的锁信息
------- TRX HAS BEEN WAITING 5 SEC FOR THIS LOCK TO BE GRANTED:
RECORD LOCKS space id 75 page no 3 n bits 80 index PRIMARY of table `test1`.`tb4001` trx id 10573 lock_mode X waiting
Record lock, heap no 2 PHYSICAL RECORD: n_fields 6; compact format; info bits 0
 0: len 8; hex 8000000000000001; asc         ;;
 1: len 6; hex 00000000293c; asc     )<;;
 2: len 7; hex b90000001c0110; asc        ;;
 3: len 4; hex 80000002; asc     ;;
 4: len 1; hex 32; asc 2;;
 5: len 4; hex 80000002; asc     ;;

------------------
---TRANSACTION 10571, ACTIVE 681 sec
2 lock struct(s), heap size 1136, 5 row lock(s), undo log entries 1
MySQL thread id 52, OS thread handle 140674621650688, query id 1201 127.0.0.1 admin

##=========================================##
会话2:
SET SESSION tx_isolation=‘REPEATABLE-READ‘;
START TRANSACTION;
SELECT @@GLOBAL.tx_isolation, @@SESSION.tx_isolation;

delete from  tb4001 where c3=8;
##执行结果:会话2被阻塞
使用SHOW ENGINE INNODB STATUS \G查看阻塞发生时的锁信息
------- TRX HAS BEEN WAITING 4 SEC FOR THIS LOCK TO BE GRANTED:
RECORD LOCKS space id 75 page no 3 n bits 80 index PRIMARY of table `test1`.`tb4001` trx id 10573 lock_mode X waiting
Record lock, heap no 2 PHYSICAL RECORD: n_fields 6; compact format; info bits 0
 0: len 8; hex 8000000000000001; asc         ;;
 1: len 6; hex 00000000293c; asc     )<;;
 2: len 7; hex b90000001c0110; asc        ;;
 3: len 4; hex 80000002; asc     ;;
 4: len 1; hex 32; asc 2;;
 5: len 4; hex 80000002; asc     ;;

------------------
---TRANSACTION 10571, ACTIVE 790 sec
2 lock struct(s), heap size 1136, 5 row lock(s), undo log entries 1
MySQL thread id 52, OS thread handle 140674621650688, query id 1201 127.0.0.1 admin

==============================================================================

按照非唯一索引更新

在可重复读的事务隔离级别下,按照非主键非唯一索引进行更新和删除,会对满足条件的行加行锁+满足条件的区域加gap锁
如果更新或删除条件为c1=4且c1列上有非唯一索引则:
1、允许其他会话插入c1<>4的记录,但不允许插入c1=4的记录
2、允许其他会话更新c1<>4的记录,但不允许将记录更新为c1=4的记录
3、允许其他会话删除c1<>4的记录。
4、允许插入\删除\修改在c1列索引上与c1=4相邻的记录,虽然操作会影响gap锁的边界值。

##=========================================##
测试数据:
CREATE TABLE `tb4001` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT,
  `c1` int(11) DEFAULT NULL,
  `c2` varchar(200) DEFAULT NULL,
  `c3` int(11) DEFAULT NULL,
  PRIMARY KEY (`id`),
  KEY `idx_c1` (`c1`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;

insert into tb4001(c1,c2,c3) values(2,2,2);
insert into tb4001(c1,c2,c3) values(4,4,4);
insert into tb4001(c1,c2,c3) values(7,7,7);
insert into tb4001(c1,c2,c3) values(8,8,8);

##=========================================##
##测试1:在没有索引的列上更新
##事务隔离级别:RR
会话1:
SET SESSION tx_isolation=‘REPEATABLE-READ‘;
START TRANSACTION;
SELECT @@GLOBAL.tx_isolation, @@SESSION.tx_isolation;
update tb4001 set c2=777 where c1=7;

##=========================================##
会话2:
begin;
SET SESSION tx_isolation=‘REPEATABLE-READ‘;
START TRANSACTION;
SELECT @@GLOBAL.tx_isolation, @@SESSION.tx_isolation;
insert into tb4001(c1,c2,c3) values(9,9,9);

会话2未被阻塞成功执行

##=========================================##
会话2:
SET SESSION tx_isolation=‘REPEATABLE-READ‘;
START TRANSACTION;
SELECT @@GLOBAL.tx_isolation, @@SESSION.tx_isolation;
insert into tb4001(c1,c2,c3) values(7,7,7);

##执行结果:会话2被阻塞
使用SHOW ENGINE INNODB STATUS \G查看阻塞发生时的锁信息
---TRANSACTION 10600, ACTIVE 7 sec inserting
mysql tables in use 1, locked 1
LOCK WAIT 2 lock struct(s), heap size 1136, 1 row lock(s), undo log entries 1
MySQL thread id 53, OS thread handle 140674620851968, query id 1317 127.0.0.1 admin update
insert into tb4001(c1,c2,c3) values(7,7,7)
------- TRX HAS BEEN WAITING 7 SEC FOR THIS LOCK TO BE GRANTED:
RECORD LOCKS space id 75 page no 4 n bits 72 index idx_c1 of table `test1`.`tb4001` trx id 10600 lock_mode X locks gap before rec insert intention waiting
Record lock, heap no 5 PHYSICAL RECORD: n_fields 2; compact format; info bits 0
 0: len 4; hex 80000008; asc     ;;
 1: len 8; hex 8000000000000004; asc         ;;

------------------
---TRANSACTION 10598, ACTIVE 270 sec
4 lock struct(s), heap size 1136, 3 row lock(s), undo log entries 1
MySQL thread id 52, OS thread handle 140674621650688, query id 1306 127.0.0.1 admin

##=========================================##
会话2:
SET SESSION tx_isolation=‘REPEATABLE-READ‘;
START TRANSACTION;
SELECT @@GLOBAL.tx_isolation, @@SESSION.tx_isolation;
delete from  tb4001 where c1=8;
会话2未被阻塞成功执行

##=========================================##
会话2:
SET SESSION tx_isolation=‘REPEATABLE-READ‘;
START TRANSACTION;
SELECT @@GLOBAL.tx_isolation, @@SESSION.tx_isolation;
update tb4001 set c2=888 where c1=8;
会话2未被阻塞成功执行

##=========================================##
会话2:
SET SESSION tx_isolation=‘REPEATABLE-READ‘;
START TRANSACTION;
SELECT @@GLOBAL.tx_isolation, @@SESSION.tx_isolation;
delete from  tb4001 where c1=4;
会话2未被阻塞成功执行

##=========================================##

==============================================================================

按照非唯一索引+条件更新

在可重复读事务隔离级别下,按照对非唯一索引列进行更新,会对扫描到的所有索引记录进行更新,无论该记录是否满足WHERE中的其他条件。

##=========================================##
测试数据:
CREATE TABLE `tb4001` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT,
  `c1` int(11) DEFAULT NULL,
  `c2` varchar(200) DEFAULT NULL,
  `c3` int(11) DEFAULT NULL,
  PRIMARY KEY (`id`),
  KEY `idx_c1` (`c1`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;

insert into tb4001(c1,c2,c3) values(2,2,2);
insert into tb4001(c1,c2,c3) values(4,4,4);
insert into tb4001(c1,c2,c3) values(4,4,44);
insert into tb4001(c1,c2,c3) values(7,7,7);
insert into tb4001(c1,c2,c3) values(8,8,8);

##=========================================##
##会话1:
##事务隔离级别:RR
会话1:
SET SESSION tx_isolation=‘REPEATABLE-READ‘;
START TRANSACTION;
SELECT @@GLOBAL.tx_isolation, @@SESSION.tx_isolation;
update tb4001 set c2=444 where c1=4 and c3=4;

##=========================================##
##会话2:
SET SESSION tx_isolation=‘REPEATABLE-READ‘;
START TRANSACTION;
SELECT @@GLOBAL.tx_isolation, @@SESSION.tx_isolation;
update tb4001 set c2=444 where c1=4 and c3=44;

会话2未被阻塞成功执行
##执行结果:会话2被阻塞
mysql tables in use 1, locked 1
LOCK WAIT 2 lock struct(s), heap size 1136, 1 row lock(s)
MySQL thread id 76, OS thread handle 140674621384448, query id 1636 127.0.0.1 admin updating
update tb4001 set c2=444 where c1=4 and c3=44
------- TRX HAS BEEN WAITING 13 SEC FOR THIS LOCK TO BE GRANTED:
RECORD LOCKS space id 79 page no 4 n bits 72 index idx_c1 of table `test1`.`tb4001` trx id 10781 lock_mode X waiting
Record lock, heap no 3 PHYSICAL RECORD: n_fields 2; compact format; info bits 0
 0: len 4; hex 80000004; asc     ;;
 1: len 8; hex 8000000000000002; asc         ;;

------------------
---TRANSACTION 10780, ACTIVE 52 sec
4 lock struct(s), heap size 1136, 5 row lock(s), undo log entries 1
MySQL thread id 75, OS thread handle 140674621916928, query id 1618 127.0.0.1 admin

##=========================================##

==============================================================================

按照非唯一组合索引更新

##=========================================##
##测试数据
CREATE TABLE `tb4001` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT,
  `c1` int(11) DEFAULT NULL,
  `c2` varchar(200) DEFAULT NULL,
  `c3` int(11) DEFAULT NULL,
  PRIMARY KEY (`id`),
  KEY `idx_c1_c3` (`c1`,`c3`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;

insert into tb4001(c1,c2,c3) values(2,2,2);
insert into tb4001(c1,c2,c3) values(4,4,4);
insert into tb4001(c1,c2,c3) values(4,4,44);
insert into tb4001(c1,c2,c3) values(7,7,7);
insert into tb4001(c1,c2,c3) values(8,8,8);

##=========================================##
##会话1:
##事务隔离级别:RR
会话1:
SET SESSION tx_isolation=‘REPEATABLE-READ‘;
START TRANSACTION;
SELECT @@GLOBAL.tx_isolation, @@SESSION.tx_isolation;
update tb4001 set c2=444 where c1=4 and c3=4;

##=========================================##
##会话2:
SET SESSION tx_isolation=‘REPEATABLE-READ‘;
START TRANSACTION;
SELECT @@GLOBAL.tx_isolation, @@SESSION.tx_isolation;
update tb4001 set c2=444 where c1=4 and c3=44;

会话2未被阻塞成功执行

##=========================================##
##会话2:
SET SESSION tx_isolation=‘REPEATABLE-READ‘;
START TRANSACTION;
SELECT @@GLOBAL.tx_isolation, @@SESSION.tx_isolation;
update tb4001 set c2=444 where c1=2 and c3=2;

会话2未被阻塞成功执行

##=========================================##
##会话2:
SET SESSION tx_isolation=‘REPEATABLE-READ‘;
START TRANSACTION;
SELECT @@GLOBAL.tx_isolation, @@SESSION.tx_isolation;
insert into tb4001(c1,c2,c3) values(4,4,3);

会话2被阻塞
##=========================================##

==============================================================================

==============================================================================

==============================================================================

==============================================================================

原文地址:https://www.cnblogs.com/gaogao67/p/10411360.html

时间: 2024-09-30 06:00:49

MySQL Transaction--RR事务隔离级别下加锁测试的相关文章

浅谈mysql中不同事务隔离级别下数据的显示效果

事务的概念 事 务是一组原子性的SQL查询语句,也可以被看做一个工作单元.如果数据库引擎能够成功地对数据库应用所有的查询语句,它就会执行所有查询,如果任何一条查 询语句因为崩溃或其他原因而无法执行,那么所有的语句就都不会执行.也就是说,事务内的语句要么全部执行,要么一句也不执行. 事务的特性:acid,也称为事务的四个测试(原子性,一致性,隔离性,持久性) automicity:原子性,事务所引起的数据库操作,要么都完成,要么都不执行consisitency:一致性,事务执行前的总和和事务执行后

mysql中不同事务隔离级别下数据的显示效果--转载

事务是一组原子性的SQL查询语句,也可以被看做一个工作单元.如果数据库引擎能够成功地对数据库应用所有的查询语句,它就会执行所有查询,如果任何一条查询语句因为崩溃或其他原因而无法执行,那么所有的语句就都不会执行.也就是说,事务内的语句要么全部执行,要么一句也不执行. 事务的特性:acid,也称为事务的四个测试(原子性,一致性,隔离性,持久性) automicity:原子性,事务所引起的数据库操作,要么都完成,要么都不执行 consisitency:一致性,事务执行前的总和和事务执行后的总和是不变的

mysql 4中事务隔离级别

SQL标准定义了4类隔离级别,包括了一些具体规则,用来限定事务内外的哪些改变是可见的,哪些是不可见的.低级别的隔离级一般支持更高的并发处理,并拥有更低的系统开销.Read Uncommitted(读取未提交内容) 在该隔离级别,所有事务都可以看到其他未提交事务的执行结果.本隔离级别很少用于实际应用,因为它的性能也不比其他级别好多少.读取未提交的数据,也被称之为脏读(Dirty Read).Read Committed(读取提交内容) 这是大多数数据库系统的默认隔离级别(但不是MySQL默认的).

第36讲 谈谈MySQL支持的事务隔离级别,以及悲观锁和乐观锁的原理和应用场景

在日常开发中,尤其是业务开发,少不了利用 Java 对数据库进行基本的增删改查等数据操作,这也是 Java 工程师的必备技能之一.做好数据操作,不仅仅需要对 Java 语言相关框架的掌握,更需要对各种数据库自身体系结构的理解.今天这一讲,作为补充 Java 面试考察知识点的完整性,关于数据库的应用和细节还需要在实践中深入学习.今天我要问你的问题是,谈谈 MySQL 支持的事务隔离级别,以及悲观锁和乐观锁的原理和应用场景?典型回答所谓隔离级别(Isolation Level),就是在数据库事务中,

面试必问的MySQL锁与事务隔离级别

之前多篇文章从mysql的底层结构分析.sql语句的分析器以及sql从优化底层分析, 还有工作中常用的sql优化小知识点.面试各大互联网公司必问的mysql锁和事务隔离级别,这篇文章给你打神助攻,一飞冲天. 锁定义 锁是计算机协调多个进程或线程并发访问某一资源的机制. 在数据库中,除了传统的计算资源(如 CPU.RAM.I/O等)的争用以外,数据也是一种需要用户共享的资源.如何保证数据并发访问的一致性.有效性是所有数据库需要解决的问题,锁冲突也是影响数据库并发性能的一个重要因素. 锁分类 从性能

30秒读懂mysql四种事务隔离级别

一.事务的基本要素(ACID) 1.原子性(Atomicity):事务开始后所有操作,要么全部做完,要么全部不做,不可能停滞在中间环节.事务执行过程中出错,会回滚到事务开始前的状态,所有的操作就像没有发生一样.也就是说事务是一个不可分割的整体,就像化学中学过的原子,是物质构成的基本单位.  2.一致性(Consistency):事务开始前和结束后,数据库的完整性约束没有被破坏 .比如A向B转账,不可能A扣了钱,B却没收到. 3.隔离性(Isolation):同一时间,只允许一个事务请求同一数据,

mysql中的事务隔离级别及可重复读读提交详细分析(mvcc多版本控制/undo log)

一.事物隔离级别 读未提交(read uncommitted)是指,一个事务还没提交时,它做的变更就能被别的事务看到.通俗理解,别人改数据的事务尚未提交,我在我的事务中也能读到. 读提交(read committed)是指,一个事务提交之后,它做的变更才会被其他事务看到.通俗理解,别人改数据的事务已经提交,我在我的事务中才能读到. 可重复读(repeatable read)是指,一个事务执行过程中看到的数据,总是跟这个事务在启动时看到的数据 是一致的.当然在可重复读隔离级别下,未提交变更对其他事

MySQL四种事务隔离级别

一.事务(Transaction)的基本要素(ACID) 1.原子性(Atomicity):事务开始后所有操作,要么全部做完,要么全部不做,不可能停滞在中间环节.事务执行过程中出错,会回滚到事务开始前的状态,所有的操作就像没有发生一样.也就是说事务是一个不可分割的整体,就像化学中学过的原子,是物质构成的基本单位. 2.一致性(Consistency):事务开始前和结束后,数据库的完整性约束没有被破坏 .比如A向B转账,不可能A扣了钱,B却没收到. 3.隔离性(Isolation):同一时间,只允

深入理解mysql锁与事务隔离级别

一.锁 1.锁的定义 锁即是一种用来协调多线程或进程并发使用同一共享资源的机制 2.锁的分类 从性能上分类:乐观锁和悲观锁 从数据库操作类型上分类:读锁和写锁 从操作粒度上分类:表锁和行锁 2.1 从性能上分类 2.1.1 乐观锁 乐观锁顾名思义就是操作的时候很乐观,认为操作不会产生并发问题(不会有其他线程对数据进行修改),因此不会上锁.但是会在更新时判断其他线程再这之前有没有对数据进行修改,一般会使用版本号机制或CAS算法实现. 2.1.1.1 版本号机制 实现方式: 取出记录时,获取当前ve