MySQL事务隔离级别
事务
事务是由单独的一个或者多个SQL语句组成,是一个最小的不可再分割的单元,这一组操作里面的所有的执行,要么全部成功、要么全部不成功。如果有一个执行不成功,则全部进行回滚。
例如: 去银行转账,用户用A账户转100元到B账户,首先A账户需要扣减100元,B账户需要增加100元,这两个操作必须都要全部成功完成,如果有其中一个操作出现失败,例如A账户扣减完100,B账户增加100元时出现错误,则A账户增加的100也要回滚,否则就会导致金额不对。事务就是保证这两个操作要么都成功,要么都不成功。
事务的并发问题
脏读
事务A读取到了事务B已经修改还未提交的数据,此时如果事务B回滚,则事务A读取到的数据就是无效的,这种数据就是"脏数据",事务A根据这个数据进行操作可能就会出现错误。
不可重复读
事务A读取某一个字段时,事务B对该字段进行了修改,事务A再次读取该字段时,读取到的值和第一次读取到的值不一致。
幻读
事务A查询表中数据,事务B新增了数据到该表中,事务A再次查询表中数据,两次查询结果不一致。
不可重复读和幻读的区别:不可重复读针对的是修改,幻读针对的是新增或删除。
不可重复读指的是两次读取过来的数据内容不一样,幻读指的是两次读取过来的数据条数不一样。
串行化
事务A和事务B同时操作数据时,如果事务A修改了数据,没有提交数据时,事务B想增加、修改、删除数据,都必须等待事务A提交,事务B才能执行。
事务的隔离级别
读取未提交(Read Uncommitted)
允许事务读取到其他事务未提交的数据。事务A可以读取到事务B修改但是未提交的数据。隔离级别最低,上面出现的并发问题都没解决。
读取已提交(Read Committed)(Oracle默认)
事务只能看到其他事务已经提交的数据。事务A只能读取事务B已经提交的数据。可以避免脏读,但是不可以避免不可重复读和幻读。
可重复读(Repeatable Read)(MySQL默认)
事务多次读取时可以保证读取到相同的值,在事务期间,禁止其他事务对该数据进行更新操作。事务A读取某商品数量100,在此期间禁止事务B更新该商品数量,事务A再次读取该商品数量还是100.可以避免脏读和不可重复读,但是无法避免幻读。
可串行化(Serializable)
保证事务读取到相同的数据,在事务期间,禁止其他事务对该表进行新增、更新、删除操作。