对事务的理解

什么是事务?

事务是数据库管理系统执行过程中的一个逻辑单位,由一个有限的数据库操作序列构成。事物的操作要么完全地执行,要么完全地不执行。

在关系数据库中,一个事务可以是一条SQL语句,一组SQL语句或整个程序。事务有ACID四个特性:

1、原子性(Atomicity):即不可分割,要么全部执行,要么全部不执行。事务的正确执行会使数据库从一种状态转换成另一种状态,所以如果事务的所有的子事务都提交成功,那么事务成功执行,数据库状态发生变化;如果事务中的任何一个子事务提交失败,那么事务失败,之前所有执行的子事务都会被回滚,数据库回到事务执行前的状态

2、一致性(consistency):事务的执行必须是使数据库从一种正确的状态转移到另外一种正确的状态

3、隔离性(isolation):在事务完全执行成功之前,不对其他的事务产生影响,也不会受到其他事务的影响

4、持久性(durability):即事务在成功提交后,他对数据库的改变是永久的,即使数据库发生灾难性的故障,也能够通过数据库操作日志和数据备份找回原有的数据。

 

事务的作用

数据库的事务:

1、他能够为数据库操作提供了一个从失败恢复到正常状态的方法

2、当多个应用程序并发访问数据库时,能够在这些应用程序提供一个隔离方法,能够防止各个应用之间的操作互相干扰

系统的事务:

1、对业务进行一系列的操作时,要么全部执行,要么全部不执行

 

事务在并发情况下带来的问题

事务在为数据库操作带来很多便利的同时,也带来了许多问题。

1、脏读(针对未提交数据):事务A对某一条数据进行了操作,但是并未提交,此时事务B读取到了事务A还未提交的操作后的该条数据,如果事务A发生回滚,事务B读到的数据就是错误的,这种现象被称为脏读

具体例子:灰太狼查看自己家里银行卡里的存款(卡里拥有5000元),灰太狼查看存款(事务A开启),同时红太狼进行取款(事务B开启),取走1000元(事务B并未提交),此时灰太狼查看到的存款为4000元(查看到了红太狼取完款后的银行卡余额,事务A结束),但是红太狼又将1000元存回去(事务B结束),实际上此时卡里还有5000元,但是灰太狼误以为只有4000元,这就是一种典型的脏读现象。

2、不可重复读(针对其他事物提交前后,读取数据本身的对比):事务A读取到了某一条数据,然后事务A执行他的逻辑,此时事务B修改了该条数据,事务A再次读取到该条数据时,发现和第一次读取到的数据不一致,这种现象被称为不可重复读

具体例子:灰太狼查看自己家里银行卡里的存款(卡里拥有5000元),灰太狼查看存款(事务A开启),查看到存款为5000元,同时红太狼进行取款(事务B开启),取走1000元(事务B结束),然后灰太狼再次查看存款为4000元(事务A结束),在同一个事务内两次读到的银行卡余额不同,这就是一种典型的不可重复读现象。

3、幻读(针对其他事物提交前后,读取数据条数的对比):事务A读取到了符合一个条件的某几条(N条)数据,事务B增添了符合该条件的(M条)几条数据,并提交,事务A再次读取符合该条件的数据时,读到的条数为(N+M条)与第一次读取到的条数不相等,这种现象被称为幻读

具体例子:灰太狼抓到了几只羊,出门买调料前,数了一遍锅里的羊(事务A开启),有3只,就出门了。灰太狼出门后红太狼又从羊村抓了2只羊回来放到锅里(事务B),灰太狼回家后数了一下锅里的羊,有5只羊,灰太狼还以为自己第一次数错了,这便是一种典型的幻读现象。

 

事务的隔离级别

事务的隔离级别拥有四种:

1、Read Uncommitted(读未提交):事务修改数据后即使未提交,其他事务也可以读取到该事务修改后未被提交的数据,所以这个级别的隔离机制无法解决脏读、不可重复读、幻读中的任何一种

2、Read Committed (读已提交):能够读取到那些已经提交的数据,能够防止脏读,但是无法解决不可重复读和幻读的问题

3、Repeatable Read(重复读):在数据读取出来后对其加锁,防止别人修改他,即读取了一条数据,改事务不结束,别的事务就不能修改这条记录,能够解决脏读、不可重复读的问题,但是幻读依旧解决不了

4、Serializable(串行化):最高级别的事务隔离级别,不管拥有多少事务,只有执行完一个完整的事务后才能执行下一个事务,这样能够避免脏读、不可重复读、幻读的问题

 

事务的隔离级别设置的越高,事务对数据进行操作的行为就越安全,但是安全的代价是事务执行效率的降低,所以事务的隔离级别并不是设置的越高越好,实际开发中我们需要在安全性和执行效率之间做一个权重比

 

查看事务的隔离级别以及修改的命令

 查看mysql事务隔离级别命令

查看会话当前隔离级别:SELECT @@TX_ISOLATION;

查看系统当前隔离级别:SELECT @@GLOBAL.TX_ISOLATION;

修改会话当前的隔离级别:SET SESSION TRANSACTION ISOLATION LEVEL SERIALIZABLE; (READ UNCOMMITTED || READ COMMITTED || REAPEATABLE READ)

修改系统当前的隔离级别:SET GLOBAL TRANSACTION ISOLATION LEVEL SERIALIZABLE;(READ UNCOMMITTED || READ COMMITTED || REAPEATABLE READ)

 

注:作为入坑不久的小白,第一次写博客,如有不对的地方,请指出,谢谢!

 

posted @ 2019-06-19 11:18  寄昙说  阅读(1590)  评论(1编辑  收藏  举报