什么是事务
事务是逻辑上的一组操作,要么全部执行,要么全部放弃。最典型的例子就是银行转账,此消彼长是原则,全部的操作必须是一个事务,中间环节若失败,则回滚至最初状态。
事务的特性
事务的特性即:ACID
- 原子性(Atomicity):事务是最小的执行单位,不允许分割。
- 一致性(Consistency):执行事务前后,数据保持一致,多个事务对同一个数据读取的结果是相同的。
- 隔离性(Isolation):并发访问数据库时,一个用户的事务不被其他事务所干扰,各并发事务之间数据库是独立。
- 持久性(Durability):一个事务被提交之后。它对数据库中数据的改变是持久的,即使数据库发生故障也不应该对其有任何影响。
事务在并发下的问题
并发场景下,多个事务操作同样的数据。可能带来以下问题:
- 脏读 (Dirty read):读取了未提交生效的数据。即一个事务update期间(未提交),另一个事务read。
- 丢失修改 (Lost to modify):修改了前序事务未修改完成的数据。即一个事务update期间(未提交),另一个事务也update。
- 不可重复读 (Unrepeatable read):两次读取read&read期间,另一个事务做了修改update操作。
- 幻读 (Phantom read):两次读取read&read期间,另一个事务做了新增insert / 删除delete操作。
解决事务并发问题:事务隔离
为了解决以上并发导致的问题,SQL标准定义了四种隔离级别(从低到高):
- 读取未提交 (Read-Uncommitted) :最低级别,允许读取未提交的数据。
- 读取已提交 (Read-Committed) :只允许读取已经提交的数据。可以防止脏读!
- 可重复读 (Repeatable-Read) :同一字段的多次读取结果是一致的,除非自身进行了修改。可以防止脏读、不可重复读。MySQL InnoDB 存储引擎的默认支持的隔离级别(使用了Next-Key Lock 锁算法,因此InnoDB的该级别可以达到可串行化的SQL标准级别)。
- 可串行化 (Serializable) :最高级别,完全遵从ACID隔离级别,所有事务相互独立,互不干扰。可以防止脏读、不可重复读、幻读。
| 隔离级别 | 防止脏读 | 防止不可重复读 | 防止幻读 |
|---|---|---|---|
| READ-UNCOMMITTED | × | × | × |
| READ-COMMITTED | √ | × | × |
| REPEATABLE-READ | √ | √ | × |
| SERIALIZABLE | √ | √ | √ |
PS 可以在SQL中使用以下命令来查看隔离级别:SELECT @@transaction_isolation
参考资料:(文章仅做交流学习,侵权即删!!)