1、事务和事务的特性
事务指的就是一系列原子性的操作,这些操作要么全做,要么全都不做。事务是由引擎层支持的,而MylSAM不支持事务,InnoDB支持事务。
- 原子性
- 一致性
- 隔离性
- 持久性
2、事务的隔离性
事务的隔离性是指事务之间互不干扰,相互隔离。Mysql有四种隔离级别,分别是未提交读,提交读,可重复读和串行化。
- 未提交读:一个事务可以看到其他事务未提交的变更。这种隔离性是最低的,一般不会采用这种隔离级别。未提交读可能会导致脏读、不可重复读和幻读。
- 提交读:一个事务读取到其他事务已经提交的变更。提交读可能会导致不可重复读和幻读。
- 可重复读:事务在启动时看到的数据,和在执行过程中看到的是一致的,不会被更改。但是有可能会读到其他事务新增的数据,也就是可能会导致幻读。
- 串行化:这种隔离级别下,“写”加“写”锁,“读”加“读”锁,出现读写冲突时,其他事务需要等待前一个事务执行完成。这种隔离级别下,并发度较低。
- 脏读:就是会提交其他事务未提交的脏数据。
- 不可重复读:是指一个事务里面多次读取到的结果不一样。不可重复读是由更新造成的。- 幻读是由于其他事务新增数据,导致这个事务读取到的行数不一样。
- 幻读:是指当事务不是独立执行时发生的一种现象,例如第一个事务对一个表中的数据进行了修改,这种修改涉及到表中的全部数据行。同时,第二个事务也修改这个表中的数据,这种修改是向表中插入一行新数据。那么,以后就会发生操作第一个事务的用户发现表中还有没有修改的数据行,就好象发生了幻觉一样.
- 脏写:
3、脏读 (针对未提交数据)
如果一个事务中对数据进行了更新,但事务还没有提交,另一个事务可以“看到”该事务没有提交的更新结果,这样造成的问题就是,如果第一个事务回滚,那么,第二个事务在此之前所“看到”的数据就是一笔脏数据。
4、不可重复读(针对其他提交前后,读取数据本身的对比)
不可重复读取是指同一个事务在整个事务过程中对同一笔数据进行读取,每次读取结果都不同。如果事务1在事务2的更新操作之前读取一次数据,在事务2的更新操作之后再读取同一笔数据一次,两次结果是不同的,所以,Read Uncommitted也无法避免不可重复读取的问题。
5、幻读(针对其他提交前后,读取数据条数的对比)
幻读是指同样一笔查询在整个事务过程中多次执行后,查询所得的结果集是不一样的。幻读针对的是多笔记录。在Read Uncommitted隔离级别下, 不管事务2的插入操作是否提交,事务1在插入操作之前和之后执行相同的查询,取得的结果集是不同的,所以,Read Uncommitted同样无法避免幻读的问题。
注意:快照读与当前的区别
select快照读(照片)
当你执行select *之后,在A与B事务中都会返回4条一样的数据,这是不用想的,当执行select的时候,innodb默认会执行快照读,相当于就是给你目前的状态找了一张照片,以后执行select 的时候就会返回当前照片里面的数据,当其他事务提交了也对你不造成影响,和你没关系,这就实现了可重复读了,那这个照片是什么时候生成的呢?不是开启事务的时候,是当你第一次执行select的时候,也就是说,当A开启了事务,然后没有执行任何操作,这时候B insert了一条数据然后commit,这时候A执行 select,那么返回的数据中就会有B添加的那条数据......之后无论再有其他事务commit都没有关系,因为照片已经生成了,而且不会再生成了,以后都会参考这张照片。
update、insert、delete 当前读
当你执行这几个操作的时候默认会执行当前读,也就是会读取最新的记录,也就是别的事务提交的数据你也可以看到,这样很好理解啊,假设你要update一个记录,另一个事务已经delete这条数据并且commit了,这样不是会产生冲突吗,所以你update的时候肯定要知道最新的信息啊。