数据库事务介绍

完成特定的业务的多个数据库 DML 操作步骤则为事务

数据库事务特性

原子性 (Atomicity): 一个事务中的多个 DML 操作, 要么同时执行成功, 要么同时执行失败

一致性 (Consistency): 事务执行之前和事务执行之后, 数据库中的数据是一致的, 完整性和一致性不能被破坏

隔离性 (Isolation): 数据库允许多个事务同时执行 (张三借 Java 书的同时允许李四借 Java 书), 多个必行的事务之间不能相互影响

持久性 (Durability): 事务完整之后, 对数据库的操作是永久的

MySQL 事务管理

用于保证事务的原子性

自动提交

在 MySQL 中, 默认 DML 指令的执行是自动提交的, 当执行一个 DML 指令之后会自动同步到数据库中

事务管理

开启事务, 就是关闭自动提交

  • 在开始事务第⼀个操作之前, 执行 start transaction 开启事务
  • 依次执行事务中的每个 DML 操作
  • 如果在执行的过程中的任何位置出现异常, 则执行 rollback 回滚事务
  • 如果事务中所有的 DML 操作都执行成功, 则在最后执行 commit 提交事务
  1. # 借书事务
  2. # 【开启事务】 (关闭自动提交——手动提交)
  3. start transaction;
  4. # 操作 1: 在借书记录表中添加记录
  5. insert into records(snum, bid, borrow_num, is_return, borrow_date)
  6. values('1007', 4, 2, 0, sysdate());
  7. select aaa; -- 执行失败
  8. #【事务回滚】(清楚连接缓存中的操作, 撤销当前事务已经执行的操作)
  9. rollback;
  10. # 操作 2: 修改图书库存
  11. update books set book_stock = book_stock - 2 where book_id = 4;
  12. # 【提交事务】(将连接缓存中的操作写入数据文件)
  13. commit;

事务隔离级别

数据库允许多个事务并行, 多个事物之间是隔离的、相互独立的

如果事务之前不相互隔离并且操作同一数据时, 可能会导致数据的一致性被破坏

MySQL 数据库事务隔离级别

  • 读未提交 (read uncommitted)

一个事务可以读取另一个事务执行但未提交的数据, 但可能会导致出现脏读

脏读: 一个事务读取到了另一个事务中未提交的数据

  • 读已提交 (read committed)

一个事务只能读取另一个事务已经提交的数据, 避免了脏读, 但可能会导致不可重复读, 也称为虚读

不可重复读 (虚读): 在同一个事务中, 两次相同的查询读取的数据不一致

  • 可重复读 (repeatable read)

一个事务执行第一次查询之后, 在事务结束之前其他事务不能修改对应的数据, 但可以添加新的数据, 虽然避免了不可重复读 (虚读), 但可能导致幻读

幻读: 第一个事务对数据表中的数据进行修改 (修改某字段所有纪录为相同数据) 然后查询, 在查询之前, 第二个事务向数据表新增 (与第一个事务修改的数据不同) 了一条数据, 导致第一个事务认为修改了所有数据, 但却查询出了于修改后不一致的数据 (第二个事务修改后的数据)

  • 串行化 (serializable)

同时只允许一个事务对数据表进行操作, 避免了脏读、虚读、幻读问题

设置数据库事务隔离级别

可以通过设置数据库默认的事务隔离级别来控制事务之前的隔离性, 也可以通过客户端与数据库连接来设置事务间的隔离性 (在应用程序中设置—spring)

MySQL 数据库默认的隔离级别是可重复度

查看 MySQL 数据库默认的隔离级别

  1. # MySQL 8.0.3 之前
  2. select @@tx_isolation;
  3. # MySQL 8.0.3 之后
  4. select @@transaction_isolation;

**设置 MySQL 默认隔离级别

  1. set session transaction isolation level <read committed>;