跳至正文

Mysql事务和隔离级别

事务

将一组SQL语句,封装到事务中(工作单元)执行,事务中的语句要么全部执行成功,要么全部执行失败!

Mysql中事务是由存储引擎层实现的,常用支持事务的存储引擎Innodb.

应用场景

对数据一致性要求非常高的业务场景,例如:经典转账场景,用户A转账100元给用户B, 如果执行失败,需要使A和B的账户余额恢复正常,否则会造成某一方账户余额错误

ACID原则

原子性 Atomicity

不可分割的最小独立工作单元,事务内的SQL被当做一个整体执行

一致性 Consistency

保证数据一致性.简单的讲就是事务内的SQL要么执行全部成功,要么全部失败,

隔离性 Isolation (隔离级别)

一个事务内的操作(执行的SQL)在最终提交以前,对其它事务是不可见的.

持久性 Durability

事务提交后,数据将永久存储

自动提交

Mysql默认的采用自动提交模式(AUTOCOMMIT),不显式开启事务(start transaction)时,每次执行的sql都会提交

查看事务是否自动开启 show variables status like ‘autocommit’



开启关闭 set autocommit = 0 (OFF) set autocommit = 1(ON)

隔离级别(事务的)

SQL标准提供了四种事务的隔离级别:

读未提交(read uncommitted)

事务中的(数据)变更,即使事务未提交,在其它事务中也可以读取.也称为脏读(dirty read)

应用场景:

读提交(read committed)

事务中的(数据)变更,在事务提交后,在其它事务中才可以被读取,也称为不可重复读,

执行同样的查询,两次可能会得到不同的结果

可重复读(repeatable read) MySQL默认隔离级别

事务在执行过程中读取的数据,总是跟事务启动时读取的到的数据保持一致,未提交变更对其它事务同样不可见.会出现幻读.事务A读取一行记录,此时事务B插入新的记录,事务A再次读取数据,先前读取的一行会出现重复.
Innodb通过MVCC解决了幻读.

串行化(serializable)

强制事务串行执行,写操作加写锁,读操作加读锁,出现写锁冲突是后一个事务必须等待前一个事务执行完成才能继续执行

对比

隔离级别脏读可能性不可重复读幻读可能性加锁读
READ UNCOMMITyesyesyes no
READ COMMITEDnoyesyesno
REPEATABLE READnonoyesno
SERIALIZABLEnononoyes

查看隔离级别指令

show variables like 'transaction_isolation';

配置的方式:

将mysql启动参数 transaction-isolation 的值设置成对应的隔离级别

隔离级别演示案例