初识MySQL事务

了解了MySQL事务中的隔离级别,继续学习关于事务的基本知识。

死锁

死锁是指两个或者多个事务在同一个资源上相互占用,并请求锁定对方占用的资源,从而导致恶性循环的现象。当多个事务试图以不同的顺序锁定资源时,就可能会产生死锁。多个事务同时锁定同一个资源时,也会产生死锁。

锁的行为和顺序是和存储引擎相关的。以同样的顺序执行语句,有些存储引擎会产生死锁,有些则不会。死锁的产生有双重原因: 有些是因为真正的数据冲突,这种情况通常很难避免,有些则完全是由于存储引擎的实现方式导致的。

InnoDB中处理死锁的两种策略:

  • 设置锁等待超时时间,通过innodb_lock_wait_timeout,意味着当死锁出现后,第一个被锁住的线程要过了设定时间才退出,其他线程才可能继续执行。
  • 主动死锁检测: innodb_deadlock_detect默认设置为on,主动死锁检测在发生死锁时,能够快速发现并处理。

事务日志

事务日志可以提高事务的效率,使用事务日志,存储引擎在修改表的数据时只需要修改其内存拷贝,再把该修改行为记录到持久在硬盘上的事务日志中,而不用每次都将修改的数据本身持久到磁盘。事务日志采用的是追加的方式。因此写日志的操作是将磁盘上的一小块区域内的顺序I/O,而不像随机I/O需要在磁盘的多个地方移动磁头,所以事务日志的方式相对来说要快的多。事务日志持久化后,内存中修改的数据可以在后台慢慢刷回磁盘。

启动方式

  • 显示启动事务,begin或start transaction,直到显式地执行commit或者rollback回滚,该事务结束。
  • set autocommit=1,也是MySQL默认采用的自动提交模式。每个查询都会被当作一个事务执行提交操作。
    1
    2
    3
    4
    5
    6
    7
    8
    9
    mysql> show variables like 'autocommit';
    +---------------+-------+
    | Variable_name | Value |
    +---------------+-------+
    | autocommit | ON |
    +---------------+-------+
    1 row in set, 1 warning (0.00 sec)

    mysql>

隐式和显式锁定

InnoDB采用两阶段锁定协议(two-phase locking protocol)。在事务执行过程中,随时可以执行锁定,锁只有在执行commit或rollback的时候才会释放,并且所有的锁是在同一时候被释放。属于隐式锁定,InnoDB会根据隔离级别在需要的时候自动加锁。
InnoDB也支持通过特定的语句进行显式锁定,这些语句不属于SQL规范,实际应尽量避免使用:

1
2
SELECT ... LOCK IN SHARE MODE
SELECT ... FOR UPDATE
0%