浅谈mysql事务和隔离级别
事务
事务就是一组原子性的sql查询,或者说是一个独立的工作单元,如果数据库引擎能够成功执行对数据库应用该组查询的全部语句,那么就执行该组查询,如果其中一条语句因为崩溃或者其他原因导致失败,那么全部不会执行。
例1:
START TRANSACTION;
SELECT * FROM apply_flow WHERE id = 1;
UPDATE apply_flow SET order_number = '231321312' WHERE id = 2;
UPDATE apply_flow SET order_number = '324312123' WHERE id = 3;
COMMIT;
1事务的特性(ACID)
1.1原子性(atomicity)
一个事务必须被视作一个不可分隔的最小工作单元,整个事务中的所有的操作要么全部成功,要么全部失败,对于一个事务来说,不可能只执行其中的一部分操作。这就是事务的原子性。
1.2一致性(atomicity)
数据库总是从一个一致性的状态转换为另外一个一致性的状态,在例1中,一致性确保了。即使在执行到第三和第四条语句之间时系统崩溃,因为事务没有提交,所以事务中的修改也不会保存。
1.3隔离性(atomicity)
一个事务在提交前,对其他的事务是不可见的。
1.4持久性(atomicity)
一旦事务提交,则其所做的修改就会永久保存,即使系统崩溃,修改后的数据也不会丢失。
2.事务的隔离级别
未提交读(READ UNCOMMITTED)
事务中的修改,在没有提交前对于其他的事务也是可见的。事务可以读取未提交的数据,这也就是赃读。这个级别会导致许多的问题,在性能上将,也不会比其他的隔离级别好太多,但是缺乏其他的隔离级别的好处,除非有特别必要的理由,在实际上应用很少。
提交读(READ COMMITTED)
大多数的数据库系统默认隔离级别都是READ COMMITTED (mysql不是),一个事务开始时,只能看见已经提交的事务的修改,或者来说,一个事务从开始到提交之前,所做的任何修改对于其他的事务来说是不可见的。这个隔离级别也叫做不可重复读。
可重复读( READ REPEATABLE)
可重复读解决了赃读的问题,该级别保证了在同一个事务中多次读取同样的记录的结果也是一致的。但是无法解决另外一个问题,幻读。幻读是指当某个事务在读取某个范围的记录时,另外一个事务又在这个范围中插入了新的记录,在当前的事务再次读取这个范围的记录时,会产生幻行。Innodb和XtraDB存储引擎中通过多版本并发控制解决的幻读的问题。
可重复读时mysql默认的隔离级别。
可串行化(READ SERIALIZABLE)
SERIALIZABLE是最高的隔离级别,它通过强制事务串行执行,避免了前面所说的幻读的问题,简单来说,SERIALIZABLE会在读取每一行数据上加锁,所以可能导致大量的超时和锁争用的问题。在实际上也很少用到这个隔离级别。只有在非常需要确保数据的一致性而且可以接受没有并发的情况下,才会考虑这个级别。