数据库事务的特性与事务隔离级别

                             数据库事务的特性与隔离级别

事务

    事务简单的理解就是要在数据库上执行的一组业务相关的SQL语句,是关系型数据库的最基础执行单位;但不是每个数据库的每个引擎都支持事务,例如我们使用的MySQL数据库的MyISAM就不支持事务。

ACID-数据库事务的四大特性

    A-Atomicity(原子性)

    指数据库事务的操作要么全部执行,要么全部不执行,也就是说事务的操作是原子性的,具有不可分割的特性;

    C-Consistency(一致性)

    指数据库在事务操作前后都保持了一致性状态,即事务操作前后数据库只是从一种一致性状态转变为另一种一致性状态;

    I-Isolation(隔离性)

    指数据库允许多个并发事务同时对其数据进行读写和修改的能力,隔离性可以防止多个事务并发执行时由于交叉执行而导致数      据的不一致。事务隔离分为不同级别,包括读未提交(Read uncommitted)、读提交(read committed)、可重复读(repeatable read)和串行化(Serializable)。;

    D-Durability(持久性)

    指数据库事务处理结束后,对数据的修改就是永久的,即便系统故障也不会丢失。

以上四个特性基本描述了事务在执行前执行时以及执行后的特性。

MySQL数据库事务的相关操作

1.查看MySQL数据库当前的引擎以及是否支持事务

    登陆数据库后输入show engines;

从图中可以看出MySQL默认的引擎是InnoDB,该数据库引擎支持事务和行级锁以及外键和保存点等。

2.查看当前数据库事务的隔离级别

 在数据库命令行输入:select @@tx_isolation;

当前的事务隔离级别是可重复读 REPEATABLE-READ。

3.设置数据库事务隔离级别

也可以是

4.InnoDB的事务隔离级别分类

READ UNCOMMITTED、READ COMMITTED、REPEATABLE READ和SERIALIZABLE

5.事务处理语句

    如果当前的引擎不支持数据库事务,需要设置引擎为支持数据库事务的InnoDB,MySQL默认的引擎是InnoDB,所以一般不需要修改引擎。默认的事务隔离级别是REPEATABLE READ,也不需要修改,如果不满足对要求可以进行重新设置。在设置完隔离级别后可以开启事务,开启事务的方式是begin命令或者start transaction命令,提交事务是commit命令,事务回滚是rollback命令;也可以通过设置变量autocommit变量来处理事务,比如设置autocommit为1来达到事务的自动提交,如果autocommit为0则需要手段提交。

    保存点,是对数据库事务的细粒度管理,在一个数据库是事务中可以有多个保存点,每个保存点有对应的id,事务回滚的时候可以指定回滚的保存点,也可以删除保存点。Savepoint identifier  设置事务保存点;RELEASE SAVEPOINT identifier;删除事务保存点;ROLLBACK TO identifier;把事务回滚到标记点。

数据库脏读,不可重复读,幻读(虚读)与事务隔离级别

1.脏读

    数据库事务并发处理时,事务A对表中的某行记录进行了操作,此时事务B对该记录进行了查询,之后A事务进行了回滚操作,那么B事务刚才读取数据就是脏读,所以脏读就是并行事务间读取了尚未提交的数据。

2.不可重复读

    数据库事务并发处理时,事务A对表中的某记录进行了读取,接着事务B对事务进行修改并提交了,之后事务A对该记录再次进行读取,发现与之前读取的结果不相同,尽管多次再读取还是和之前读取的结果不相同,这就是不可重复读。不可重复读和脏读的区别在与前者读取的是未提交的数据,后者读取了已提交的数据。

3.幻读(虚读)

    数据库事务并发处理时,事务A对某表中的记录进行了条件统计,例如条件是名字中带"中"字的,就在事务A统计期间,某条符合条件的记录被事务B修改了,事务A再次进行统计时发现统计结果与上次不同,这就是幻读也叫虚读。幻读与不可重复读的区别在于前者是对于多条记录的操作时因为另外一个事务的介入导致整体的结果异常,而后者是对同一条记录的读取,所以两者的区别主要是在数量上的区别。

4.数据库模拟演示

4.1 脏读模拟

在两个数据库客户端中模拟脏读现象(两个客户端AB模拟事务AB,事务隔离级别是uncomiited,默认都已开启事务):

   A客户端对user表中的数据进行查询,结果如图:

B客户端对user表中用户名为rose的记录更新年龄为16:

此时在A客户端中查询所有的user,发现名为rose的user年龄为16:

B客户端现在进行事务回滚:

A客户端再次进行查看,发现名为rose的用户年龄为12岁不是16岁:

4.2 不可重复读模拟

在两个数据库客户端中模拟不可重复读现象(两个客户端AB模拟事务AB,事务隔离级别是uncomiited,默认都已开启事务):

A客户端对user表中的名为rose的user进行查询:

B客户端对该记录进行了修改,将其age改为16,并提交。

A客户端再对该记录进行查询,发现第一次之后查询的结果和第一次不重复。

4.3幻读(虚读)模拟

在两个数据库客户端中模拟幻读现象(两个客户端AB模拟事务AB,事务隔离级别是uncomiited,默认都已开启事务):

A客户端统计所有的记录数:

此时B客户端删除了其中一条记录:

A客户端再次查询发现记录数与之前的不相符

事务隔离级别

  脏读 不可重复读 幻读

Read uncommitted 

可能出现 可能出现 可能出现

Read committed

不可能出现 可能出现 可能出现

Repeatable read

不可能出现 不可能出现 可能出现

Serializable

不可能出现 不可能出现 不可能出现

    上述的四个隔离级别是ISO/ANSI SQL92定义的,但是不是每个数据库都完全实现了,但是MySQL是完全实现了的。那么是数据库事务隔离的实现是怎样的呢?其实是数据库索,MySQL中会有行级锁和表锁以及间隙锁,InnoDB的行级锁其实是索引加锁,例如避免不可重复读时,可以对该记录进行锁定,避免幻读时可以对全表进行加锁也就是使用表锁。更加详细的学习将会后续进行!

猜你喜欢

转载自blog.csdn.net/tony_java_2017/article/details/81230872