数据库事务介绍
完成特定的业务的多个数据库 DML 操作步骤则为事务
数据库事务特性
原子性 (Atomicity): 一个事务中的多个 DML 操作, 要么同时执行成功, 要么同时执行失败
一致性 (Consistency): 事务执行之前和事务执行之后, 数据库中的数据是一致的, 完整性和一致性不能被破坏
隔离性 (Isolation): 数据库允许多个事务同时执行 (张三借 Java 书的同时允许李四借 Java 书), 多个必行的事务之间不能相互影响
持久性 (Durability): 事务完整之后, 对数据库的操作是永久的
MySQL 事务管理
用于保证事务的原子性
自动提交
在 MySQL 中, 默认 DML 指令的执行是自动提交的, 当执行一个 DML 指令之后会自动同步到数据库中
事务管理
开启事务, 就是关闭自动提交
- 在开始事务第⼀个操作之前, 执行
start transaction
开启事务 - 依次执行事务中的每个 DML 操作
- 如果在执行的过程中的任何位置出现异常, 则执行
rollback
回滚事务 - 如果事务中所有的 DML 操作都执行成功, 则在最后执行
commit
提交事务
# 借书事务
# 【开启事务】 (关闭自动提交——手动提交)
start transaction;
# 操作 1: 在借书记录表中添加记录
insert into records(snum, bid, borrow_num, is_return, borrow_date)
values('1007', 4, 2, 0, sysdate());
select aaa; -- 执行失败
#【事务回滚】(清楚连接缓存中的操作, 撤销当前事务已经执行的操作)
rollback;
# 操作 2: 修改图书库存
update books set book_stock = book_stock - 2 where book_id = 4;
# 【提交事务】(将连接缓存中的操作写入数据文件)
commit;
事务隔离级别
数据库允许多个事务并行, 多个事物之间是隔离的、相互独立的
如果事务之前不相互隔离并且操作同一数据时, 可能会导致数据的一致性被破坏
MySQL 数据库事务隔离级别
- 读未提交 (read uncommitted)
一个事务可以读取另一个事务执行但未提交的数据, 但可能会导致出现脏读
脏读: 一个事务读取到了另一个事务中未提交的数据
- 读已提交 (read committed)
一个事务只能读取另一个事务已经提交的数据, 避免了脏读, 但可能会导致不可重复读, 也称为虚读
不可重复读 (虚读): 在同一个事务中, 两次相同的查询读取的数据不一致
- 可重复读 (repeatable read)
一个事务执行第一次查询之后, 在事务结束之前其他事务不能修改对应的数据, 但可以添加新的数据, 虽然避免了不可重复读 (虚读), 但可能导致幻读
幻读: 第一个事务对数据表中的数据进行修改 (修改某字段所有纪录为相同数据) 然后查询, 在查询之前, 第二个事务向数据表新增 (与第一个事务修改的数据不同) 了一条数据, 导致第一个事务认为修改了所有数据, 但却查询出了于修改后不一致的数据 (第二个事务修改后的数据)
- 串行化 (serializable)
同时只允许一个事务对数据表进行操作, 避免了脏读、虚读、幻读问题
设置数据库事务隔离级别
可以通过设置数据库默认的事务隔离级别来控制事务之前的隔离性, 也可以通过客户端与数据库连接来设置事务间的隔离性 (在应用程序中设置—spring)
MySQL 数据库默认的隔离级别是
可重复度
查看 MySQL 数据库默认的隔离级别
# MySQL 8.0.3 之前
select @@tx_isolation;
# MySQL 8.0.3 之后
select @@transaction_isolation;
**设置 MySQL 默认隔离级别
set session transaction isolation level <read committed>;