文章目录
一、教学视频
教学讲解视频:视频地址
二、事务简介
事务是一组操作的集合,事务会把所有操作作为一个整体一起向系统提交或撤销操作请求,即这些操作要么同时成功
,要么同时失败
。
三、事务操作
1.查看事务提交方式
SELECT @@AUTOCOMMIT;
2.设置事务提交方式
1为自动提交
,0为手动提交
,该设置只对当前会话
有效。
SET @@AUTOCOMMIT = 0;
3.开启事务
START TRANSACTION 或 BEGIN TRANSACTION;
4.提交事务
COMMIT;
5.回滚事务
ROLLBACK;
示例代码:
-- 设置为手动提交
set @@autocommit = 0;
-- 查询提交方式
select @@autocommit;
-- 开启事务
start transaction ;
-- 更新数据
update tests set num = num - 100 where id = 2;
-- 提交事务
COMMIT;
-- 回滚事务
ROLLBACK;
四、事务四大特性ACID
- 原子性(Atomicity):事务是不可分割的最小操作单元,要么全部成功,要么全部失败。
- 一致性(Consistency):事务完成时,必须使所有数据都保持一致状态。
- 隔离性(Isolation):数据库系统提供的隔离机制,保证事务在不受外部并发操作影响的独立环境下运行。
- 持久性(Durability):事务一旦提交或回滚,它对数据库中的数据的改变就是永久的。
五、并发事务的问题
问题 | 描述 |
---|---|
脏读 | 一个事务读到另一个事务还没提交的数据 |
不可重复读 | 一个事务先后读取同一条记录,但两次读取的数据不同 |
幻读 | 一个事务按照条件查询数据时,没有对应的数据行,但是再插入数据时,又发现这行数据已经存在 |
六、并发事务隔离级别
隔离级别 | 脏读 | 不可重复读 | 幻读 |
---|---|---|---|
Read uncommitted | √ | √ | √ |
Read committed | × | √ | √ |
Repeatable Read(默认) | × | × | √ |
Serializable | × | × | × |
- √表示在当前隔离级别下该问题会出现。
- Serializable 性能
最低
;Read uncommitted 性能最高
,数据安全性最差
。
-- 查看事务隔离级别:
SELECT @@TRANSACTION_ISOLATION; -- 5.7.2之后
SELECT @@TX_ISOLATION; -- 5.7.2之前
-- 设置事务隔离级别:
SET [ SESSION | GLOBAL ] TRANSACTION ISOLATION LEVEL {READ UNCOMMITTED | READ COMMITTED | REPEATABLE READ | SERIALIZABLE };
-- SESSION 是会话级别,表示只针对当前会话有效,GLOBAL 表示对所有会话有效
七、代码实例
1.脏读实例
事务A
SET SESSION TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;
set @@autocommit = 0;
start transaction;
update tests set num = num - 100 where id = 2;
ROLLBACK;
事务B
SET SESSION TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;
set @@autocommit = 0;
start transaction;
select * from tests where id = 2;
COMMIT;
我们先把两个事务的隔离级别都设置为读未提交
,当A事务执行完update指令但还没有执行回滚的时候,B事务select出来的数据是已经update后的数据
,这就是脏读。
2.不可重复读实例
事务A
SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED;
set @@autocommit = 0;
start transaction;
update tests set num = num - 100 where id = 2;
COMMIT;
事务B
SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED;
set @@autocommit = 0;
start transaction;
select * from tests where id = 2;
COMMIT;
我们会发现,在A事务提交之前
和提交之后
,我们在B事务中同样的查询语句,查询的结果不一致
,这就是不可重复读的问题。
3.幻读的实例
事务A
SET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READ;
set @@autocommit = 0;
start transaction;
insert into tests VALUE(3, 1000);
COMMIT;
事务B
SET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READ;
set @@autocommit = 0;
start transaction;
select * from tests where id = 3;
insert into tests VALUE(3, 1000);
commit;
在事务A执行完insert之后但还没有提交,事务B此时查询id为3的数据是查不到
的,然后A事务进行了提交
,此时B事务还是查不到
id为3的数据,但是insert又会报主键冲突
的错误,这就是幻读,明明查不到数据,但却插入不了。
4.串行化的实现
事务A
use db_online_supermarket_system;
SET SESSION TRANSACTION ISOLATION LEVEL SERIALIZABLE ;
set @@autocommit = 0;
start transaction;
select * from tests where id = 10;
commit;
事务B
use db_online_supermarket_system;
SET SESSION TRANSACTION ISOLATION LEVEL SERIALIZABLE ;
set @@autocommit = 0;
start transaction;
insert into tests VALUE(10, 1000);
commit;
如果我们在A事务先执行了select查询语句之后
的话,当我们B事务执行到insert时候会阻塞等待
,直到A事务提交之后才会继续执行B事务。