mysql数据库学习总结五(事务)-事务特性、事务隔离级别及测试

mysql数据库学习总结五(事务)

一、事务及特性

概述:事务是有一步或几部数据库操作序列组成的逻辑执行单元,这系列的操作要么全部执行,要么全部不执行,

事务具有的四个特性:原子性(Atomicity)、一致性(consistency)、隔离性(isolation)和持续性(durability)

  • 原子性:事务是应用中最小的执行单位,就如原我们认为的自然界中最小的颗粒,具有不可再分的特征一样。(不成功,就还原)
  • 一致性:事务执行的结果,必须从一个一致性状态到另一个一致性状态。(用哪个连接都是查的结果都是一样的)
  • 隔离性:每个事务的执行互不干扰,任意一个事务的内部操作对其他事务都是隔离的。(就是自己干自己的,谁也不管谁)
  • 持久性:事务一旦提交,就会被记录在磁盘中,通常是保存进物理数据库中。(更改后就提交,保存入磁盘)

注意:原子性、隔离性、持久性,都是为了数据一致性而存在的

二、事务的隔离级别

  • 读未提交 read uncommitted
  • 读已提交 read committed
  • 可重复读 repeatable read
  • 序列化 serializable

三、四种隔离级别所产生的的异常

隔离级别 异常情况
读未提交 脏读、不可重复读、幻读
读已提交 不可重复读、幻读
可重复读 幻读
序列化

注:我们使用的数据库隔离级别一般为可重复读

四:通过实验验证事务的隔离性

1.打开mysql的命令行,将自动提交事务关闭(默认是开启的)
–查询是否开启自动提交,默认为1,0表示关闭

SELECT @@autocommit;

–设置关闭

set autocommit = 0;

2.数据的准备
–创建数据库

create database tran

–切换数据库

use tran

–创建表结构

create table psn(id int(2) primary key,name varchar(10)) engine=innodb;

–插入数据

insert into psn values(1,'zhangsan');
insert into psn values(2,'lisi');
insert into psn values(3,'wangwu');
commit;

记得提交,已经将自动提交关闭了

3.测试1脏读 read uncommint

set session transaction isolation level read uncommitted;
A:start transaction;
A:select * from psn;
B:start transaction;
B:select * from psn;
A:update psn set name='msb';
A:selecet * from psn
B:select * from psn;  --读取的结果msb。产生脏读,因为A事务并没有commit,读取到了不存在的数据
A:commit;
B:select * from psn; --读取的数据是msb,因为A事务已经commit,数据永久的被修改

4.测试2:当使用read committed的时候,就不会出现脏读的情况了,当时会出现不可重复读的问题

set session transaction isolation level read committed;
A:start transaction;
A:select * from psn;
B:start transaction;
B:select * from psn;
--执行到此处的时候发现,两个窗口读取的数据是一致的
A:update psn set name ='zhangsan' where id = 1;
A:select * from psn;
B:select * from psn;
--执行到此处发现两个窗口读取的数据不一致,B窗口中读取不到更新的数据
A:commit;
A:select * from psn;--读取到更新的数据
B:select * from psn;--也读取到更新的数据
--发现同一个事务中多次读取数据出现不一致的情况

5.测试3:当使用repeatable read的时候(按照上面的步骤操作),就不会出现不可重复读的问题,但是会出现幻读的问题

set session transaction isolation level repeatable read;
A:start transaction;
A:select * from psn;
B:start transaction;
B:select * from psn;
--此时两个窗口读取的数据是一致的
A:insert into psn values(4,'sisi');
A:commit;
A:select * from psn;--读取到添加的数据
B:select * from psn;--读取不到添加的数据
B:insert into psn values(4,'sisi');--报错,无法插入数据
--此时发现读取不到数据,但是在插入的时候不允许插入,出现了幻读,设置更高级别的隔离级别即可解决

猜你喜欢

转载自blog.csdn.net/weixin_47402482/article/details/108926731