先介绍下并发环境下事务执行可能发生的错误:
1.写覆盖:一个事务执行时,最后需要写回数据A,在这期间,另一个事务读取了未写回的数据项A,然后也更新了A。那么最后A只可能为两个事务更新的值中的一个,另一个更新就丢失了。更新一个未提交的值,会覆盖别人的更新。
2.脏读:读取了未提交的值,与写覆盖比较容易混淆,脏读指的是,一个事务中有一个写操作修改了值,但是这个事务还有后续的操作,没有提交,然后另一个事务读取了这个修改以后的值,最后前面的事务因为错误回滚了,那么后一个事务读取的值就没有意义了,是一个错误的值。所以需要等前一个事务提交以后再读取。脏读与写覆盖的区别在于另一个事务是在修改之前还是之后操作数据的。
3.重复读:指的是一个事务需要读一个数据两次,在读取期间,另一个事务修改了这个值,最后导致两次读取的值不同。
4.幻读:幻读发生在数据插入过程,针对的是一个数据的集合。对这个集合的操作正好忽略了刚插入的数据。
以上都是事务并行执行时可能发生的错误。所以需要隔离事务。隔离的级别越高,并行的效率越低,因此数据库可以设置隔离级别。
mysql默认的隔离级别是重复读。
应用程序提交到mysql服务的事务,其实可以理解为执行的程序,有的是计算,有的是io,因此事务是可以并行的,当然这是宏观的,微观可能是几个io线程级别的并行。隔离级别就是控制事务的并行程度的。
Read uncommitted:只能避免写覆盖;当一个事务读时,别的事务在写这个数据时可以不提交就读。
Read committed:还可以避免脏读;事务读时,别的事务必须写完才可以,只能读提交的值。
Repeatable read:还可以避免重复读;
序列化:都可以避免;