数据库事务的特性以及MySQL数据库的隔离级别

前言

了解数据库事务的特性,能够让我们更好的理解编程的时候对数据库事务的控制。本篇文章主要讲解了数据库事务的特性以及MySQL数据库在不同的事务隔离级别下遇到的不同情况。

数据库事务的概念

数据库事务是访问并可能更新数据库中各个数据项的一个程序执行单元,通常包含对数据库进行读或者写的一个操作序列
一个典型的数据库事务如下:

begin transaction //事务开始
SQL1
SQL2
commit/rollback//事务结束或者回滚

数据库事务的特性

数据库事务的特性有四个,简称ACID,即原子性(Atomicity)、一致性(Consistency)、隔离性(Isolation)、持久性(Durability)。下面我们来说明一下这四个特性。

原子性(Atomicity)

原子性是指,同一个事务中的多个数据库的操作是一起完成的,要么所有的数据库操作都操作成功,如果有一个数据库的操作失败,则其他的操作也都会回滚。也就是说,要么全部成功,要么全部回滚。

一致性(Consistency)

一致性是指,一个事务或者多个事务在开始前的数据的状态和结束后的数据的状态要保持一致。这里的一致性有点抽象,我们举个例子来说明:假设在数据库中库存表中的某商品的库存总量为10,购买量为0,剩余量为10。现在有两个用户购买了1件该商品,那么在这两个用户购买完成后,该商品的购买量应该为2,剩余量应该为8,它们的总和等于库存量10,而不应该为其他的数值。

隔离性(Isolation)

隔离性是指,不同事务之间,他们是互相独立的,不会相互的干扰。就是说,一个事务里对某一数据进行操作,不会影响其他事务对同样数据的操作。他们操作完成以后对数据库的影响和他们串行执行时的结果一样

持久性(Durability)

持久性是指,一个事务一旦提交成功,它对数据库的修改是持久的。任何事务或者系统故障都不会导致数据的丢失。

事务并发会产生的异常

事务的四大特性,可以很好的规范程序员根据不同的业务场景以及数据库不同的隔离级别,对数据库的事务进行合理的操作,从而来避免一些多个事务并发执行时所产生的异常情况。事务并发执行时,产生以下几种异常情况。

数据库事务的特性以及MySQL数据库的隔离级别
这四种异常会因为数据库的隔离级别不同而产生,接下来我们先来讲一下MySQL数据的四种隔离级别。

MySQL数据库的四个隔离级别

MySQL数据库的四个隔离级别从低到高依次为:1.读未提交(read uncommitted);2.读已提交(read committed);3.可重复读(repeatable read)--MySQL默认的隔离级别;4.串行化(serializable)

以上四种隔离级别,分别会产生的异常情况如下图所示:
数据库事务的特性以及MySQL数据库的隔离级别

读未提交(read uncommitted)

如果有两个事务,都在操作同一条数据的一个整型字段paramA的值(假设两个事务没操作之前值为0),其中一个事务A正在读取变量paramA的值的时候,而另一个事务B更改了变量paramA的值(更改为1),但是还没有提交paramA的值,那么此时事务A读取到的paramA的值为1。这里发生了脏读,如果事务B提交失败的话,那么事务A拿到的变量paramA的值与数据库本来的值是不一致的。此级别同样会产生幻读不可重复读的现象(同一事务不同时间读取的记录条数不一致)。

读已提交(read committed)

如果有两个事务,都在操作同一条数据的一个整型字段paramA的值(假设两个事务没操作之前值为0),其中一个事务A正在读取paramA的值的时候,而另一个事务B更改了paramA的值(更改为1),但是还没有提交paramA的值,那么此时事务A读取到的paramA的值为0;如果事务A在读取变量paramA的值时,事务B已经更改了paramA的值为1,并且提交了事务,那么事务A读取到的值就为1。这个隔离级别会导致同一事务在多次读取一条记录的某个值时可能会读取不同的结果,也即不可重复读的情况;当然,也会产生幻读的现象。

可重复读(repeatable read)

还是上述场景,如果事务A在第一次读取paramA的时候,事务B没有更改paramA的值,那么事务A读取到的paramA的值为0,在事务A第二次读取paramA的时候,事务B更改了paramA的值并提交了事务,则事务A第二次读取到的paramA的值仍为0。此隔离级别为MySQL数据库的默认隔离界别,但这种隔离级别也会产生幻读

串行化(serializable)

仍以上述两个事务为例,此时如果事务A读取某一表的一条数据中字段paramA的值(此时为0),此时如果事务B如果想修改该表中该记录字段paramA的值时,则修改不了,处于等待状态;但是事务B如果是读取字段paramA的值则允许读取。如果事务A在更改该表该记录的字段paramA的值,则事务B不能做任何操作(读取、增加、修改、删除)的操作,只有等事务A结束后才允许进行操作。这种隔离级别容易产生超时和锁竞争情况。

脏读(Dirty Read)

幻读(Phantom Read)

不可重复读(Unrepeatable Read)

丢失更新(Lost Update)

数据库事务的特性以及MySQL数据库的隔离级别

上一篇:lyt经典版MySQL基础——进阶8:联合查询


下一篇:lyt经典版MySQL基础——常见的数据类型