mysql可重复读实验_Mysql可重复读测试

mysql的InnoDB索引存储引擎在RR(REPEATABLE READ)隔离级别下读取的情况

测试建表

create table test_transaction (

id bigint(20) NOT NULL AUTO_INCREMENT COMMENT ‘主键’,

int_f int not null default 0 comment ‘字段1’,

char_f varchar(50) not null default ” comment ‘字段2’,

time_f TIMESTAMP not null default CURRENT_TIMESTAMP comment ‘字段3’,

PRIMARY KEY (id),

unique key uqe_int (int_f),

KEY idx_char_time (char_f,time_f)

) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT=’测试建表’;

初始准备数据

insert into test_transaction (int_f, char_f) value(520, ‘Charlotte’);

select * from test_transaction;

Part1) 起因:昨晚和光同事的一次讨论

– 获取隔离级别,确定当前是可重复度级别

SELECT @@global.tx_isolation;

– 能不能插入?插入会不会挂起,事务A能不能读取到 –

事务A

事务B

START TRANSACTION;

START TRANSACTION;

select * from test_transaction;

select * from test_transaction;

insert into test_transaction (int_f, char_f) value(521, ‘xyb’);

select * from test_transaction;

select * from test_transaction;

commit;

commit;

事务A没能读到事务B新插入的数据,事务B也没有被挂起

– 能不能删除?删除会不会挂起,事务A能不能读取到 –

事务A

事务B

START TRANSACTION;

START TRANSACTION;

select * from test_transaction;

select * from test_transaction;

delete from test_transaction where int_f=521;

select * from test_transaction;

select * from test_transaction;

commit;

commit;

事务A也还能读到事务B新删除的数据,事务B也没有被挂起

– 能不能修改?修改会不会挂起,事务A能不能读取到 –

事务A

事务B

START TRANSACTION;

START TRANSACTION;

select * from test_transaction;

select * from test_transaction;

update test_transaction set char_f=’xyb0’ where id=1;

select * from test_transaction;

select * from test_transaction;

commit;

commit;

事务A没能读到事务B的更新,事务B也没有被挂起

现象:

不管事务A查什么范围,事务B不挂起,都能插入,能修改,能删除。(乍看很震惊!有悖于S锁和X锁的理解呀!?)

Part2)

在Mysql中的InnoDB引擎,采用MVCC(Multi-Version Concurrency Control)[2],读取时候有两种来源:

- 快照读 (snapshot read),读取的是记录的可见版本 (有可能是历史版本),不用加锁,例如 select * from table where ?;

- 当前读 (current read),读取的是记录的最新版本,并且,当前读返回的记录,都会加上锁,保证其他事务不会再并发修改这条记录

- select * from table where ? lock in share mode; – 简单理解,相当于加了S锁 [3]

- select * from table where ? for update; – 简单理解,相当于加了X锁 [3]

- insert into table values (…);

- update table set ? where ?;

- delete from table where ?;

所以以前S锁和X锁的认知是在当前读所情况下,而快照读不存在任何锁。换select lock in share mode方式将刚刚的实验再来一次

– 能不能插入?插入会不会挂起,事务A能不能读取到 –

事务A

事务B

START TRANSACTION;

START TRANSACTION;

select * from test_transaction lock in share mode;

select * from test_transaction lock in share mode;

insert into test_transaction (int_f, char_f) value(521, ‘xyb’);

select * from test_transaction lock in share mode;

select * from test_transaction lock in share mode;

commit;

commit;

– 能不能删除?删除会不会挂起,事务A能不能读取到 –

事务A

事务B

START TRANSACTION;

START TRANSACTION;

select * from test_transaction lock in share mode;

select * from test_transaction lock in share mode;

delete from test_transaction where int_f=521;

select * from test_transaction lock in share mode;

select * from test_transaction lock in share mode;

commit;

commit;

– 能不能修改?修改会不会挂起,事务A能不能读取到 –

事务A

事务B

START TRANSACTION;

START TRANSACTION;

select * from test_transaction lock in share mode;

select * from test_transaction lock in share mode;

update test_transaction set char_f=’xyb0’ where id=1;

select * from test_transaction lock in share mode;

select * from test_transaction lock in share mode;

commit;

commit;

现象:

1、事务A没有commit时,事务B的查询语句能执行,但插入,修改,删除语句都会挂起

2、如果事务B先查询,然后先于事务A查询操作执行行插入,修改,删除,那么事务A读取时被挂起(和以前的S锁X锁理解一致,安心了)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
学习MySQL约束时,你可以按照以下实验步骤进行: 1. 安装MySQL:首先,你需要安装MySQL数据库管理系统。可以从MySQL官方网站下载适合你操作系统的版本,并按照安装指南进行安装。 2. 创建数据库:使用MySQL客户端连接到数据库服务器,并创建一个新的数据库。可以使用以下命令创建数据库: ```sql CREATE DATABASE mydatabase; ``` 3. 创建表:在创建表之前,你需要定义表的结构和列的属性。使用CREATE TABLE语句来创建表,并在其中指定列的名称、数据类型和约束。以下是一个示例: ```sql CREATE TABLE students ( id INT PRIMARY KEY, name VARCHAR(50) NOT NULL, age INT, class_id INT, CONSTRAINT fk_class FOREIGN KEY (class_id) REFERENCES classes(id) ); ``` 上面的示例创建了一个名为students的表,其中包含id、name、age和class_id四个列。id列被定义为主键约束,name列被定义为非空约束,class_id列被定义为外键约束。 4. 插入数据:使用INSERT INTO语句将数据插入到表中。例如: ```sql INSERT INTO students (id, name, age, class_id) VALUES (1, 'Alice', 20, 1), (2, 'Bob', 21, 2), (3, 'Charlie', 19, 1); ``` 这将向students表中插入三行数据。 5. 测试约束:尝试插入违反约束条件的数据,例如插入重复的主键值或空值。观察MySQL数据库管理系统如何拒绝这些违规操作,并返回错误消息。 6. 修改约束:如果需要修改表的约束条件,可以使用ALTER TABLE语句。例如,你可以添加或删除约束、修改列的数据类型等。 通过按照以上步骤进行实验,你将能够理解和掌握MySQL中约束的使用方法,并能够在实际项目中应用它们来确保数据库数据的完整性和一致性。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值