数据库原理-事务

178 阅读4分钟

事务的特性

事务指的是满足ACID特性的一组操作,可以通过commit提交一个事务,也可以使用rollback进行回滚。要么提交成功,要么提交失败。

  • 原子性(Atomicity)
    事务被视为不可分割的最小单元,事务所有的操作要么全部提交成功,要么全部失败回滚。

  • 一致性(Consistency)
    数据库在事务执行前后都保持一致性状态。例如:银行卡转账,建设银行卡转1000块到中国银行卡上,建设银行卡必然少了1000块,而中国银行卡多了1000块,这就是一致性。如果中途宕机了,没有将中国银行卡的1000块加上,那么这就是不符合一致性了。AID都是为了C,为了一致性

  • 隔离性(Isolation)
    一个事务所做的修改在最终提交以前,对其他事务是不可见得。例如,我的银行卡里有1000块,现在有一个事务去添加500块,在这个事务提交以前,其他事务读取银行卡里的数据还是1000块。并发执行的事务将存储的信息看作是串行(一个接一个)运行的。

  • 持久性(Durability)
    一旦事务提交,则其所做的修改将会永久保存到数据库中。即使系统发生崩溃,事务执行的结果也不能丢失

ACID之间的关系

  • 只有满足一致性,事务的执行结果才是正确的
  • 在无并发的情况下,事务串行执行,隔离性一定能够满足。此时只要能满足原子性,就一定能满足一致性。
  • 在并发的情况下,多个事务并行执行,事务不仅要满足原子性,还需要满足隔离性,才能满足一致性。
  • 事务满足持久化是为了能应对系统崩溃的情况

并发一致性问题

在并发环境下,事务的隔离性很难保证,因此会出现很多并发一致性问题

  • 丢失修改
    当两个事务同时读取同一个数据的时候,第一个事务去修改这个数据,然后第二个事务也去修改这个数据,这样第一个事务的修改就丢失了

  • 脏读
    指脏数据指在不同的事务下,当前事务可以读到另外事务未提交的数据。例如:T1修改一个数据但未提交,T2随后读取这个数据。如果T1撤销了这次修改,那么T2读取的数据是脏数据

  • 不可重复读
    指在一个事务内多次读取同一数据集合。在这一事务还未结束前,另一事务也访问了该同一数据集合并做了修改,由于第二个事务的修改,第一次事务的两次读取的数据可能不一致

  • 幻影读
    产生并发不一致性问题的主要原因是破坏了事务的隔离性,解决方式是通过并发控制来保证隔离性。并发控制可以通过封锁来实现,但是封锁操作需要用户自己控制,相当复杂。数据库管理系统提供了事务的隔离级别,让用户以一种更轻松的方式处理并发一致性问题

不可重复读是修改,幻影读是新增和删除

事务隔离级别

  • 读取未提交(read-uncommitted):最低的隔离级别,允许读取尚未提交的数据,会导致脏读,不可重复读,幻影读

  • 读取提交(read-committed):允许事务读取并发已提交的数据,可以阻止脏读,但不能阻止不可重复读,幻影读

  • 可重复读(repeatable-read):对同一字段的多次读取结果都是一致的,可以阻止脏读,不可重复读,幻影读

  • 可串行化(serializable):最高的隔离级别,所有的事务逐个执行,可以阻止脏读,不可重复读,幻影读。但会影响性能。

    类型脏读不可重复读幻影读
    读取未提交
    读取提交
    可重复读
    可串行化

MySQL5之前使用SELECT @@tx_isolation查看隔离级别,默认是可重复读(repeatable-read),MySQL8使用SELECT @@transaction_isolation查看隔离级别