在并发下事务会容易出现的一些问题:
数据更新丢失:两个事务同时操作一条数据,一个事务因为异常导致数据更新丢失
脏读 :一个失误开始读取了某行数据,另外一个事务已经更新了此数据但没有能够及时提交。这是相当危险的,因为很可能所有的操作都被回滚。
不可重复读:一个事务对同一行数据重复读取两次,但是却得到了不同的结果。例如,在两次读取的中途,有另外一个事务对该型数据进行了修改,并提交。
幻读:事务在操作过程中进行两次查询,第二次查询的结果包含了第一次查询中未出现的数据(SQL不一定一样)。这是因为在两次查询过程中有另外一个事务插入数据
在MySQL中存在(InnoDB)事务存在着4中隔离级别,不同的隔离级别对事务的处理不同。
未授权读取(未提交读 Read Uncommitted):READ-UNCOMMITTED | 0:存在脏读,不可重复读,幻读的问题。如果一个事务已经开始写数据,则另外一个数据则不会允许同时进行写操作,但允许其他事务读此行数据。隔离级别可以通过“排他写锁”实现。
授权读取(已读提交 Read committed):READ-COMMITTED | 1:解决脏读的问题,存在不可重复读,幻读的问题。这个可以通过“排他写锁”实现。读取数据的事务允许其他事务继续访问该行数据,但是未提交的写事务将会禁止其他事务访问该行。
可重复读取(Repeatable Read):REPEATABLE-READ | 2:解决脏读,不可重复读的问题,存在幻读的问题,默认隔离级别。可通过“共享锁”,“排他锁”实现。读取数据的事务将会禁止写事务(但允许读事务),写事务则禁止任何其他事务。
序列化(Serializable):SERIALIZABLE | 3:解决脏读,不可重复读,幻读,可保证事务安全,但完全串行执行,性能最低。提供严格的事务隔离。它要求事务序列化执行,事务只能一个接着一个地执行,不能并发执行。如果仅仅通过“行级锁”是无法实现事务序列化的,必须要通过其他机制保证新插入的数据不会被刚执行查询操作的事务访问到。
可以通过 show variables like '%iso%';查看当前的隔离级别