一什么是事务
1.定义
事务就是一组数据库操作(增删改SQL),要么全部执行成功,要么全部撤销失败,绝对不允许只执行一半
核心总结:事务=捆绑一组操作,保证“同生共死”
二事务四大核心特征:ACID
1. A:原子性(Atomicity)
- 含义:事务是不可分割的最小单元。
- 白话:要么全做完,要么全不做,没有 “做一半” 的情况。
- 例子:转账两步必须同时成功 / 同时失败,绝不允许只扣钱不加钱。
2. C:一致性(Consistency)
- 含义:事务执行前后,数据库的整体数据规则、完整性保持不变。
- 白话:数据永远合法,不会出现逻辑错误。
- 例子:转账前后,A+B 的总钱数不变;库存扣减后不能为负数。
3. I:隔离性(Isolation)
- 含义:多个事务同时运行时,互相不干扰、不影响。
- 白话:你跑你的事务,我跑我的事务,互不偷看、互不捣乱。
- 场景:两个人同时转账,不会出现数据错乱。
4. D:持久性(Durability)
- 含义:事务一旦提交成功,数据就永久保存到数据库。
- 白话:就算断电、宕机,提交后的数据也不会丢。
- 例子:转账提交后,哪怕服务器重启,钱的记录依然存在。
三并发性不好会出现的三大问题
如果隔离性做的不好,多个事务同时跑,就会出现 3 种脏数据问题,从严重到轻微:
1. 脏读(Dirty Read)
- 现象:读到了其他事务未提交的数据。
- 例子:A 转钱给 B,还没提交事务,C 读到 B 多了 100;结果 A 回滚了,C 读到的就是假数据(脏数据)。
2. 不可重复读(Non-Repeatable Read)
- 现象:同一个事务内,两次查询同一条数据,结果不一样。
- 原因:其他事务修改并提交了这条数据。
- 例子:你查自己余额是 1000,还没做完操作,别人转走 500,你再查变成 500。
3. 幻读(Phantom Read)
- 现象:同一个事务内,两次查询总数 / 结果集不一样。
- 原因:其他事务新增 / 删除了数据。
- 例子:你查用户表有 10 人,还没操作完,别人新增 1 个,你再查变成 11 人,像出现幻觉。
四、事务隔离级别(4 级,解决上面的问题)
数据库提供 4 个隔离级别,从低到高,级别越高越安全,但速度越慢。
| 隔离级别 | 脏读 | 不可重复读 | 幻读 | 说明 & 默认数据库 |
|---|---|---|---|---|
| 1. 读未提交(Read Uncommitted) | ✅ 有 | ✅ 有 | ✅ 有 | 最低级别,基本不用 |
| 2. 读已提交(Read Committed) | ❌ 无 | ✅ 有 | ✅ 有 | 解决脏读,Oracle 默认 |
| 3. 可重复读(Repeatable Read) | ❌ 无 | ❌ 无 | ✅ 有 | 解决前两个问题,MySQL 默认 |
| 4. 串行化(Serializable) | ❌ 无 | ❌ 无 | ❌ 无 | 最高级别,事务排队执行,最慢 |
注意
- MySQL 默认:可重复读
- Oracle 默认:读已提交
- 级别越高,并发越差,速度越慢
五、SQL 事务基础语法
1.开启事务
START TRANSACTION; -- 或者 BEGIN;2.提交事务(执行成功,永久保存)
COMMIT;3.回滚事务(执行失败,回到最初状态)
ROLLBACK;完整转账示例
-- 1. 开启事务 BEGIN; -- 2. 执行操作 UPDATE user SET money = money - 100 WHERE name = 'A'; UPDATE user SET money = money + 100 WHERE name = 'B'; -- 3. 无错误则提交,有错误则回滚 COMMIT; -- ROLLBACK;六、补充关键知识点
- 只有增删改需要事务,查询不需要。查询不修改数据,不用事务。
数据库默认自动提交MySQL 默认:每执行一条 SQL 就自动提交,相当于每条 SQL 是一个独立事务。手动事务必须用
BEGIN显式开启。事务失效场景
- 表引擎不是 InnoDB(MyISAM 不支持事务)
- 捕获了异常没回滚
- 方法不是 public / 同类内调用
适用场景转账、下单支付、库存扣减、批量数据修改,只要是多步关联操作,必须用事务。