事务的特性以及隔离级别
什么是事务
个人理解,事务就是一连串的sql语句或者说一个独立的工作单元。如果数据库能成功的对该工作单元中所有的sql语句执行成功那么该工作单元就完成。如果其中任何一个sql语句因为奔溃或者其他原因无法执行,那么所有的语句都不会执行。
换句话说,宏观来看,事务就是一个整体单位,每个单位包含一条以上的sql语句,一旦事务执行了,就意味着所有sql语句都得成功,否则的话,就不执行。
在理解事务之后,需要知道事务的目的就是为了保证数据的正确性和一致性,那么为此诞生了四个特性ACID。而为了实现这四个特性有需要许多具体的实现,其中就包括为了隔离性而产生的四个隔离级别。这四种隔离级别又产生了三个问题(脏读,不可重复读和幻读)
四种特性(ACID)
原子性
意思是说 一个事务应当作为一个不可分割的最小单位,整个事务的操作要么全部执行成功,要么全部不执行,像原子一样不可分割。
一致性
意思是说 事务总是从一个一致性的状态跳到另一个一致性的状态。
我个人理解为,涉及到的数据范围内是守恒的,也就是数据整体不变,打个比方,A给B转了200块,那么整体的钱数是没有发生变化的,A少了200,B多了200,整体变化是0;
隔离性
通常来说,一个事务的操作对于其他的事务是不可见的,也就是说一般而言事务都是独立的。但是这跟数据库的隔离级别有关
持久性
事务一旦完成,那么该事务引起的数据变化将永久生效,不会改变(除非被另外一个事务改动)
数据库的隔离级别
1. 未提交读
在这个隔离级别中,在一个事务执行的操作就算不提交也能被其他事务看到。
在这个级别中一个事务可能读到其他事务还没提交的脏数据,即可能出现脏读
2. 提交读
在一个事务提交之后,其他事务才可以看到事务的修改。此隔离级别可能会出现同一个事务执行相同的查询读到不同的数据,即不可重复读,在未提交读级别也可能出现不可重复读的情况。
3. 可重复读
这是MySQL默认的隔离级别,在事务开始的时候会保存此刻的一个快照,然后接下来这个事务的所有数据读取都是从这个快照读,所以不会出现不可重复读的情况,但是还是有可能出现幻读。
意思是读取的是快照表数据不会变化,但是进行写操作如更新的时候,更新的数量可能和预期的不同。
4. 可串行化
意思是说,事务要一个一个来,如果在一个事务中进行读操作,那么其他事务在该事务完成前只能进行读操作,如果进行写操作,那么其他事务的操作都进入等待(知道当前事务的提交)。这种级别就可以防范目前出现的脏读、不可重复读,幻读等现象
在执行不同隔离级别保证隔离性的情况下,产生的几个问题
脏读
即在当前事务中可能读取到其他事务还未提交的脏数据
不可重复读
在同一个事务中执行相同的查询语句,可能出现不同的数据,通常发生在未提交读、提交读这两个级别
幻读
在一个事务中进行写操作时修改的数量和预期不同
参考资料:粗谈MySQL事务的特性和隔离级别