事务,一系列操作构成的逻辑单元。
事务:当一个操作中的所有的小操作都执行成功这个操作才算执行成功时需要加事务。而这个“操作”就是一个事务。
原子性( Atomicity )、一致性( Consistency )、隔离性( Isolation )和持久性( Durability )
Atomicity:原子的不可拆分的,一个不可拆分的工作单元,只有当工作单元中的所有操作都成功完成,这个工作单元才算成功完成,只要有一个操作失败,则认为工作单元失败。
Consistency:不存在薛定谔的猫,事务提交之前 所有人看到的猫都是活的,事务提交之后 所有看到的猫都是死的
| 隔离级别 | 隔离级别值 | 脏读 | 不可重复读 | 幻读 |
|---|---|---|---|---|
| Read-Uncommitted (未提交读) | 0 | 是 | 是 | 是 |
| Read-Committed (提交读) | 1 | 否 | 是 | 是 |
| Repeatable-Read (可重复读) | 2 | 否 | 否 | 是 |
| Serializable (可序列化) | 3 | 否 | 否 | 否 |
隔离级别越高性能越低
1个窗口1个session
事务 autocommit:默认自动提交
Repeatable-Read (可重复读): mysql InnoDB引擎 默认事务隔离级别
Serializable (可序列化):前一个事务执行完成,才能执行后一个事务
脏读:A事务未提交,B事务就去读(相同记录)
幻读:事务A中已提交的新增记录,在事务B中查看不到,事务B中插入相同记录又会报错
实验环境:mysql 5.7
准备:
# 创建数据库,COLLATE 排序规则
CREATE DATABASE IF NOT EXISTS feature_tran DEFAULT CHARACTER SET utf8mb4 DEFAULT COLLATE utf8mb4_general_ci;
# 使用库
use feature_tran;
# 创建表
DROP TABLE IF EXISTS `employee`;
CREATE TABLE `employee` (
`id` bigint(20) UNSIGNED NOT NULL AUTO_INCREMENT COMMENT '主键',
`code` varchar(10) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '工号',
`name` varchar(30) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '姓名',
`salary` float DEFAULT NULL COMMENT '薪水',
`create_time` datetime DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = Dynamic COMMENT = "员工";
# 插入一条数据
insert into employee(`code`,`name`,`salary`) value("1000000000","xcrj",1000.0);
A事务未提交,B事务就去读(相同记录)
下面的操作都只在当前session(窗口)中有效
开启两个session,执行如下操作
#关闭事务自动提交
set autocommit = 0;
#查看MySQL自动提交状态
show variables like 'autocommit';
#未提交读
set session transaction isolation level READ UNCOMMITTED;
#查看MySQL事务隔离级别
show variables like 'tx_isolation';
| 事务A | 事务B |
|---|---|
begin; | |
begin; | |
update employee set salary=2000.0 where code="1000000000"; | |
select salaryfrom employee wherecode="1000000000"; #2000.0,脏读 | |
rollback; | |
select salaryfrom employee wherecode="1000000000"; | |
commit |

同一个事务中的两次读操作 记录数值不一致
开启两个session,执行如下操作
#关闭事务自动提交
set autocommit = 0;
#查看MySQL自动提交状态
show variables like 'autocommit';
#提交读
set session transaction isolation level READ COMMITTED;
#查看MySQL事务隔离级别
show variables like 'tx_isolation';
| 事务A | 事务B |
|---|---|
begin; | |
begin; | |
select salaryfrom employee wherecode="1000000000"; # 1000.0 | |
update employee set salary=2000.0 where code="1000000000"; | |
select salaryfrom employee wherecode="1000000000";# 2000.0,不可重复读 | |
commit | |
commit |

事务A中已提交的新增记录,在事务B中查看不到,事务
B中插入相同记录又会报错
开启两个session,执行如下操作
#关闭事务自动提交
set autocommit = 0;
#查看MySQL自动提交状态
show variables like 'autocommit';
#可重复读读
set session transaction isolation level REPEATABLE READ;
#查看MySQL事务隔离级别
show variables like 'tx_isolation';
| 事务A | 事务B |
|---|---|
begin; | |
begin; | |
insert into employee(id,code,name,salary) value(2,"1000000001","xcrj001",1100.0); | |
select * from employee where name like "xcrj%"; # 1条记录 | |
commit; | |
select * from employee where name like "xcrj%";# 还是1条记录 | |
insert into employee(id,code,name,salary) value(2,"1000000001","xcrj001",1100.0); #插入报错 | |
commit; |

#开启事务自动提交
set autocommit = 0;
#可重复读读
set session transaction isolation level REPEATABLE READ;
开始事务
执行增删改查操作
异常,回滚事务/正常,提交事务
注意,未正常关闭(rollback/commit)的事务,会影响增删改查,因为事务的本质是锁
事务未提交导致锁等待,影响增删改查
#查询事务
SELECT * from information_schema.INNODB_TRX;
# 关闭事务。mysql自动回滚
kill <trx_mysql_thread_id>
#查看MySQL事务隔离级别
show variables like 'tx_isolation';
#查看MySQL自动提交状态
show variables like 'autocommit';
#关闭事务自动提交
set autocommit = 0;
#更改事务隔离级别
#未提交读
set global/session transaction isolation level READ UNCOMMITTED;
#提交读
SET global/session transaction isolation level READ COMMITTED;
#可重复读
SET global/session transaction isolation level REPEATABLE READ;
#可串行化
SET global/session transaction isolation level SERIALIZABLE;