MySQL事务隔离

250 阅读3分钟
原文链接: www.mantis.vip

事务就是一个原子性的SQL操作,处于该事务内的SQL操作,要么全部成功,要么全部失败。在MySQL中,事务是基于引擎来实现,在MySQL中两种常用的引擎InnoDB和MyISAM,其中InnoDB是支持事务的,而MyISAM不支持。

事务的四个基本特性ACID:

  • 原子性(Atomicity)
  • 一致性(Consistency)
  • 隔离性(Isolation)
  • 持久性(Durability)

事务隔离级别

当一个SQL处于多个事务中时,就有可能出现脏读、不可重复读、幻读等问题,基于此就有了事物隔离级别的概念。 SQL中定义了四种事务的隔离级别:

隔离级别 是否脏读 是否不可重复读 是否幻读
读未提交(read uncommitted)
读已提交(read committed)
可重复读(repeatable read)
可串性化(serializable)
脏读

一个事务读取到另一个事务尚未提交的修改,就是脏读。这里的修改是指:update、insert、delete。脏读就会导致如果后一个事务回滚,他所做的操作就会撤销,前一个事务读取到的数据就会成为垃圾数据。

eg:

订单表:orders,用户发起支付请求,需要修改某条订单状态。

事务一:发起订单支付,假设订单id为99,修改订单状态从未支付改为已支付(4->5)。
事务二:查询尚未支付的订单数据,由于订单99已经在事务一种,所以此次查到的数据没有ID为99的数据。
事务一:由于余额不够,付款失败,使整个事务回滚,所以订单99仍然为未支付的订单。

所以,事务一读取到的数据是错误数据。

不可重复读

在同一个事务中,再次读取数据时,所读取到的数据和第一次的不一样,就是不可重复读。

eg:

还是订单表。

事务一:查询订单99的是否是待支付状态,此时查到的是待支付。
事务二:修改订单状态为已支付。
事务一:再次执行查询,此时就查询不到99。

幻读

事务1读取指定的where子句所返回的一些行。然后,事务2插入一个新行,这个新行也满足事务1使用的查询where子句。然后事务1再次使用相同的查询读取行,但是现在它看到了事务2刚插入的行。这个行被称为幻象,因为对事务1来说,这一行的出现是不可思议的。

幻读针对的是insert,delete操作。

eg:

事务一:查询待支付的订单列表。
事务二:想订单表中插入一条新的待支付订单数据,并提交。
事务一:再次请求查询,此时可以查到新插入的数据,出现幻读;新插入的数据如果没有提交就是脏读。

查看事务隔离级别

select @@tx_isolation;

select @@global.tx_isolation,@@session.tx_isolation;

设置事务隔离级别

set session transaction isolation level //要设置的隔离级别