一、事务
1. 什么是事务?
事务是将一组 SQL 语句作为一个单元执行的机制。如果该单元中的某个 SQL 语句发生错误,则所有 SQL 语句的执行将被取消,确保数据库的一致性和完整性。
2. 事务的四大原则(ACID)
- 原子性:事务执行必须是不可再分的,要么全部成功,要么全部失败。
- 一致性:事务应在开始和结束时保证数据库的完整性始终保持。
- 隔离性:各个事务之间互不干扰,未提交的事务数据对其他事务不可见。
- 持久性:一旦事务完成,其对数据库的修改将永久保存,而不会被回滚。
3. 事务的实现步骤
- 关闭 MySQL 自动提交:
SET autocommit = 0
- 开始一个事务:
START TRANSACTION
- 提交事务:
COMMIT
- 回滚事务:
ROLLBACK
- 开启自动提交:
SET autocomMIT = 1
4. 事务的日志
- 锁机制:实现事务的隔离性。
- 日志:
- REDO 日志(重做日志):用于恢复已提交事务的操作,确保事务的持久性。
- UNDO 日志(回滚日志):记录事务的历史状态,以支持事务的原子性和一致性。
5. MySQL 中常见的锁
- 基于属性分类:共享锁(读锁,S锁)、排他锁(写锁,X锁)。
- 基于粒度分类:表锁、行锁(记录锁、间隙锁、临键锁)。
- 基于状态分类:意向排他锁、意向共享锁。
6. 事务的隔离级别
事务并发执行时,如果缺乏适当隔离,可能会导致“脏写”、“脏读”、“不可重复读”、“幻读”等问题。
- 隔离级别:
READ_UNCOMMITTED
: 读未提交,解决脏写问题,但存在脏读和不可重复读。READ_COMMITTED
: 读已提交,解决脏写与脏读,但存在不可重复读和幻读。REPEATABLE_READ
: 可重复读,解决脏写、脏读与不可重复读,但仍可能产生幻读。SERIALIZABLE
: 串行化,所有事务串行执行,完全解决并发问题,但性能较差。
7. 事务并发时出现的问题
- 脏写:事务 A 修改了未提交的事务 B 的数据。
- 脏读:事务 A 读取了事务 B 更新但未提交的数据,若 B 回滚,A 的结果便无效。
- 不可重复读:事务 A 多次读取同一字段,若事务 B 更新该字段,A 的值随之变化。
- 幻读:在一个事务中,重复查询相同条件下的记录,第二次查询结果集包含第一次不存在的记录。
8. 避免幻读的方法
- 设置事务隔离级别:
- 可重复读:设置为可重复读,可以通过间隙锁应对幻读。
- 串行化:完全避免并发问题,但会降低系统性能。
通过理解和管理事务,可以显著提升数据库操作的安全性和一致性,为应用程序提供稳定支持。