1.事务概述
事务是一组操作的集合,要么同时成功,要么同时失败
事务举例 - 张三给李四转账:
- 张三账户 - 1000元;
- 李四账户 + 1000元。
2.事务的四大特性 - ACID
- 原子性:事务要么全部成功,要么全部失败;
- 一致性:事务完成时,必须使所有数据保持一致状态(转账前和转账后的余额之和是相等的);
- 隔离性:事务之间的执行是相互独立且隔离的(与隔离级别密不可分);
- 持久性:事务一旦提交或回滚,它对数据库中数据的改变就是永久的。
3.事务的提交与回滚
默认情况下,事务是自动提交的。一旦INSERT、DELETE、UPDATE被执行,便会提交。
而期望下的处理方式应该是:全部执行成功则提交,发生异常则回滚,因此需要关闭自动提交。
# 关闭自动提交
SET autocommit = 0;
# 开启事务
START TRANSACTION;
# 张三向李四转账
UPDATE account SET money = money - 500 WHERE name = 'zs';
UPDATE account SET money = money + 500 WHERE name = 'ls';
# 回滚事务
# ROLLBACK;
# 提交事务
COMMIT;
4.数据库并发问题
脏读
读取到另一个事务更新但未提交的数据(可能会被回滚,此时数据就是脏数据)
- T2修改记录Data1(未提交)
- T1读取记录Data1(脏读)
- T2回滚记录
不可重复读
同一条记录(重点在值):两次读取同一记录,两次读取的结果(记录的值)不一样
- T1读取记录Data1(1,“zs”,“男”)
- T2修改记录Data1(1,“ls”,“女”)
- T1再次赌气记录Data1(1,“ls”,“女”)(不可重复读)
幻读
多条记录(重点在数量):两次读取的结果数量(记录数)不一样
- T1读取表Table1(100行)
- T2插入记录Data1到Table1中并提交
- T1再次读取Table1(101行,幻读)
5.事务的隔离性:解决并发问题
MySQL支持4个隔离级,分别是
-
READ UNCOMMITTED(读未提交)
– 脏读、不可重复读、幻读。
-
READ COMMITTED(读已提交)
– 不可重复读、幻读。
-
REPEATABLE READ(可重复读) - MySQL默认隔离级,事务持续期间上行锁
– 幻读
-
SERIALIZABLE(串行化) - 事务执行时阻塞整个数据库直到事务提交或回滚
– 解决并发问题,但性能极其低下
每启动一个客户端程序,就获得一条连接,
每条连接都有一个变量@@tx_isolation,表示连接的隔离级。
相关的SQL语句如下:
# 查看当前连接的隔离级 SELECT @@tx_isolation; # 设置连接的隔离级 SET transaction isolation level READ COMMITTED; # 设置数据库的全局隔离级 SET GLOBAL transaction isolation level READ COMMITTED;