zoukankan      html  css  js  c++  java
  • MySQL中阻塞

    因为不同锁之间的兼容性关系,在有些时刻一个事务中的锁需要等待另一个事务中的锁释放它占有的资源,这就是阻塞。阻塞不是一件坏事,是为了保证事务可以并发并且正常的运行

    在InnoDB存储引擎中,参数innodb_lock_wait_timeout用来控制等待的时间(默认50秒),innodb_rollback_on_timeout用来设定是否在等待超时时对进行中的事务进行回滚操作(默认为OFF,代表不会滚)参数innodb_lock_wait_timeout是动态的,可以在运行中调整

    >set @@innodb_lock_wait_timeout=60;

    而innodb_rollback_on_timeout是静态的,不可在启动时进行修改

    当发生超时,MySQL会抛出一个1205的错误

    >BEGIN
    
    >SELECT * FROM t WHERE a=1 FOR UPDATE;
    
    ERROR 1205 (HY000): Lock wait timeout exceeded; try restarting transaction的错误。

    需要牢记,在默认情况下,InnoDB存储引擎不会回滚时引发错误异常,其实InnoDB存储引擎在大部分情况下都不会对异常进行回滚,如在一个会话中添加了如下语句

    会话A:

    >SELECT * FROM t;
    
    >BEGIN;
    
    >SELECT * FROM t WHERE a<4 FOR UPDATE;

    在会话A中开启一个事务,在Next-key Lock算法下锁定小于4的所有记录(其实也锁定了4这个记录本身)在另一个会话B中执行以下语句

    >BEGIN;
    
    >INSERT INTO t SELECT 5;
    
    >INSERT INTO t SELECT 3;
    
    ERROR 1205 (HY000): Lock wait timeout exceeded; try restarting transaction

    可以看到,在会话B中插入记录5是可以的,但是插入记录为3的时候,因为会话A中Next-Key Lock算法的关系,需要等待会话A中事务释放这个资源,所以等待后产生超时,但是在超时后用户再进行SELECT操作时发现,5这个记录依然存在

    这是因为会话B中事务虽然抛出异常,但是既没有进行COMMIT操作,也没有进行ROLLBACK。而这是非常危险的状态,因此用户必须判断是否需要COMMIT还是ROLLBACK,之后在进行下一步操作

  • 相关阅读:
    Node.js学习笔记(五) --- 使用Node.js搭建Web服务器
    express常用中间件
    MongoDb 学习笔记(一) --- MongoDb 数据库介绍、安装、使用
    如何优化网站加载时间
    Node.js学习笔记(四) --- fs模块的使用
    dns-prefetch使用整理
    puppeteer 中国区的使用
    mysql 定时任务和存储过程
    疯狂使用 leancloud (投稿文章)
    elasticsearch
  • 原文地址:https://www.cnblogs.com/olinux/p/5179174.html
Copyright © 2011-2022 走看看