数据库事务隔离

时间: 2023-12-16 admin IT培训

数据库事务隔离

数据库事务隔离

什么是事务

事务是一个改变,是一些操作的集合,用专业的术语,就是一个程序的执行单元。事务本身并不包含着以下四个特性,需要通过某些手段尽可能让该执行单元满足这四个特征,就可以称他为一个正确或完美的事务。

ACID

保证一个事务的正确性,需要保证:

Atomicity 原子性:同一个事务中的操作,要么全部成功,要么全部失败。
Consistency 一致性:数据库中的数据保证合法,满足所有的约束(比如唯一约束)
Isolation 隔离性:不同的事务不能相互影响
Durability 持久性:事务提交后,不管数据库是否崩溃重启,提交的事务所作出的修改都要生效

隔离级别

并发情况下事务引发的问题

一般情况下买多个单元操作并发执行,会出现几个问题:

脏读

指一个事务读取了另一个事务未提交的记录。当一个事务正在访问数据,并且对数据进行了修改,而这种修改还没有提交到数据库中;另外一个事务也访问这个数据,然后使用了这个未提交的数据。因为这个数据还没有提交,那么第二个事务读取到的是脏数据,依据脏数据所做的操作可能是不正确的。没保证原子性。
A事务还未提交,B就读到了A事务的结果(破坏了隔离性)

不可重复读

指在一个事务内,多次重复执行某个查询,返回的记录不一致。例如:在一个事务还没有结束时,另外一个事务修改了该数据;在第一个事务中的两次读数据之间,由于第二个事务的修改,导致两次读取到的数据可能是不一样的。这样就发生了在一个事务内两次读到的数据是不一样的,因此称为是不可重复读。没保持持久性,导致当前事务覆盖另外事务的修改。
A事务在本次事务中,对自己未操作过的数据,进行了多次读取,结果出现了不一致或记录不存在的情况。(破坏了一致性,update和delete)

幻读

指当事务不是独立执行时发生的一种现象,例如:第一个事务对表中的数据进行了批量修改(status=2);同时第二个事务也修改这个表中的数据,向表中插入一行新数据(status=1),插入的数据刚好满足第一个事务的修改条件;操作第一个事务的用户发现表中还存在没有修改的数据行(status=1),就好象发生了幻觉一样。没保持一致性。
A事务在本次事务中,对自己未操作过的数据,进行了多次读取,第一次读取记录不存在,第二次读区时记录出现了。(破坏了一致性,insert)

更新丢失

两个事务都同时更新一行数据,一个事务对数据的更新把另一个事务对数据的更新覆盖了。这是因为系统没有执行任何的锁操作,因此并发事务并没有被隔离开来。

解决(制定标准)

为了权衡隔离和并发的矛盾,ISO定义了四个事务的隔离级别,每个级别的隔离程度不同,允许出现的副作用也不同。

  • 未提交读(read-uncommitted ):最低级别,只能保证持久性
  • 已提交读( read-committed ):语句级别的(避免脏读)
  • 可重复读(repeatable-read):事务级别(避免脏读、不可重复读)
  • 串行化(serializable):事务与事务完全串行化执行,性能较低。(避免脏读、不可重复读、幻读)

实现(InnoDB)

  • 锁机制:当一个事务在执行时,阻止其他事务对数据进行操作,各个隔离级别主要体现在读取数据时加的锁和释放时机

    • RU:事务读取的时候不加锁
    • RC:事务读取的时候加行级锁(读到才加锁),一旦读完立刻释放(并不是事务结束)
    • RR:事务读取时加行级共享锁,直到事务结束才会释放
    • SE:事务读取时加表级共享锁,直到事务结束才会释放
  • MVCC机制:生成一个数据快照,并用这个快照提供一定级别的一致性的读取,也称为多版本数据控制。