数据库基础——事务

154 阅读2分钟

什么是事务

  事务是逻辑上的一组操作,要么全部执行,要么全部放弃。最典型的例子就是银行转账,此消彼长是原则,全部的操作必须是一个事务,中间环节若失败,则回滚至最初状态。

事务的特性

事务的特性即: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

参考资料:(文章仅做交流学习,侵权即删!!)

  1. Snailclimb-JavaGuide
  2. mysql的默认隔离级别