事务

事务可以简单的理解为一组SQL语句,要么全部成功执行,要么都不执行。

show variables like 'autocommit';
set autocommit = 0;
begin;
select ...
commit

特点(ACID)

  • Atomicity: 一个事务被视为最小单元,要么全部执行成功,要么全部失败回滚
  • Consistency: 数据在事务执行周期内,是一致的
  • Isolation: 事务之间是隔离的
  • Durability: 事务一旦提交,就永久保存到数据库

事务并发的问题

  • Lost Update: 多个事务对同一数据进行更新,后者会覆盖
  • Dirty Reads: 一个事务对一个数据做修改,但未提交,另一个数据读取到这些脏数据,并做进一步处理
  • Non-Repeatable Reads: 同一个事务在不同时间读取的数据不一致, 针对修改
  • Phantom Reads: 在不同时间读取的不一样,针对新增,例子

乐观锁

乐观锁认为一般情况下数据不会发生冲突,所以在数据提交更新的时候,才会对数据的冲突进行检测,数据库层面没有实现,需要自己程序实现。可以使用数据版本(version)或时间戳实现,比如MVCC

悲观锁

悲观锁认为每次取数据的时候都会被修改,所以每次拿数据时,都会上锁。s锁和x锁都是悲观锁。

类型

  • 共享锁(读锁,s锁):会阻塞其他事务修改数据, select … lock in share mode;
  • 排他锁(写锁,x锁):会阻塞其他事务读和修改数据, select … for update;

粒度

  • 表锁:锁住全表
  • 行锁:InnoDB默认,没有索引或锁定全表

死锁

未完,待续。。。

隔离级别

select @@tx_isolation;
set [ global | session ] transaction isolation level Read uncommitted | Read committed | Repeatable | Serializable;
  • Read uncommitted: 未提交读,允许脏读,也就是能读到其他事务中未提交的数据
  • Read committed: 已提交读,只能读到已提交的数据,Oracle等数据库默认
  • Repeatable read: 可重复读,在同一事务的查询都是在事务开始一致的,Innodb默认
  • Serializable: 可串行化,每次都是要获得表级共享锁,读写都相互阻塞

参考

https://tech.meituan.com/2014/08/20/innodb-lock.html