发布时间: 阅读量

数据库事务

数据库事务只是ACID吗?,安排!

前言

什么是事务?说说事务的点?事务的隔离级有哪些各有什么特点?


1.什么是事务

我现在的理解就是,一系列操作。数据库事务就是,对数据库执行的一些操作。

2.事务的特点


2.1原子性(Atomicity)


原子性是指事务包含的所有操作要么全部成功,要么全部失败回滚。例如这样一个事务,A给B转100元,此时包含两个操作A-100,B+100,如果B在减的时候出现异常,那么整个事务回滚。

2.2一致性(Consistency)


一个事务执行之前和执行之后都必须处于一致性状态。拿转账来说,假设用户A和用户B两者的钱加起来一共是5000,那么不管A和B之间如何转账,转几次账,事务结束后两个用户的钱相加起来应该还得是5000,这就是事务的一致性。上个例子,假如只执行了A-100这个操作,且执行成功,那么就满足事务的原子性,但是不满足事务的一致性,因为此时B要+100才能保证事务的一致性。

2.3隔离性(Isolation)


隔离性是当多个用户并发访问数据库时,比如操作同一张表时,数据库为每一个用户开启的事务,不能被其他事务的操作所干扰,多个并发事务之间要相互隔离。

2.4持久性(Durability)


持久性是指一个事务一旦被提交了,那么对数据库中的数据的改变就是永久性的,即便是在数据库系统遇到故障的情况下也不会丢失提交事务的操作.当我们执行一条 insert 语句后,数据库必须要保证有一条数据永久地存放在磁盘中。

3.事务的隔离级别


介绍数据库提供的各种隔离级别之前,我们先看看如果不考虑事务的隔离性,会发生的几种问题:

脏读


qqtu-pian-20181219203040

余额应该为 1100 元才对!请看 T6 时间点,事务 A 此时查询余额为 900 元,这个数据就是脏数据,它是事务 A 造成的,明显事务没有进行隔离,渗过来了,乱套了。所以脏读这件事情是非常要不得的,一定要解决掉!让事务之间隔离起来才是硬道理

不可重复读


qqtu-pian-20181219203711

事务 A 其实除了查询了两次以外,其他什么事情都没有做,结果钱就从 1000 变成 0 了,这就是重复读了。可想而知,这是别人干的,不是我干的。其实这样也是合理的,毕竟事务 B 提交了事务,数据库将结果进行了持久化,所以事务 A 再次读取自然就发生了变化。这种现象基本上是可以理解的,但在有些变态的场景下却是不允许的。毕竟这种现象也是事务之间没有隔离所造成的,但我们对于这种问题,似乎可以忽略。

幻读


qqtu-pian-20181219211838

银行工作人员,每次统计总存款,都看到不一样的结果。不过这也确实也挺正常的,总存款增多了,肯定是这个时候有人在存钱。但是如果银行系统真的这样设计,那算是玩完了。这同样也是事务没有隔离所造成的,但对于大多数应用系统而言,这似乎也是正常的,可以理解,也是允许的。银行里那些恶心的那些系统,要求非常严密,统计的时候,甚至会将所有的其他操作给隔离开,这种隔离级别就算非常高了(估计要到 SERIALIZABLE 级别了)

第一类丢失更新


qqtu-pian-20181219212342

A事务撤销时,把已经提交的B事务的更新数据覆盖了。这种错误可能造成很严重的问题,通过下面的账户取款转账就可以看出来。但是,在当前的四种任意隔离级别中,都不会发生该情况,不然绝对乱套,我都没提交事务只是撤销,就把别人的给覆盖了,这也太恐怖了。

第二类丢失更新


qqtu-pian-20181219213748

B事务覆盖A事务已经提交的数据,造成A事务所做操作丢失

归纳一下,以上提到了事务并发所引起的跟读取数据有关的问题,各用一句话来描述一下:

脏读:事务 A 读取了事务 B 未提交的数据,并在这个基础上又做了其他操作。
不可重复读:事务 A 读取了事务 B 已提交的更改数据。
幻读:事务 A 读取了事务 B 已提交的新增数据。
第一条是坚决抵制的,后两条在大多数情况下可不作考虑。

事务隔离级别图


qqtu-pian-20181219214757

mysql默认是repeatedable_read,隔离性还是很稳的


后续

学海无涯啊!
参考博文一
参考博文二