(读书笔记)mysql中的阻塞

mysql中的阻塞:

因为锁之间的不兼容性,有些时刻一个事务中的锁需要等待另外一个事务中的锁释放它所占用的资源,我们称这种方式为阻塞,有时候,为了确保事务的正常进行,就需要阻塞

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

set @@innodb_lock_wait_timeout=60;

而 innodb_rollback_on_timeout 是静态的,不可在启动时进行修改,修改时会报错,它是只读变量

在默认情况下,innodb存储引擎不会回滚超时引发的错误异常,其实Innodb存储引擎在大部分情况下都不会对异常进行回滚

下面举例

mysql> select * from auth_operation;
+----+------+--------+---------------------+--------+--------------+---------+
| id | uid  | op_uid | cr_time             | action | address      | remark  |
+----+------+--------+---------------------+--------+--------------+---------+
|  1 | 3278 |   3240 | 2020-07-11 14:44:37 |      1 | 192.168.8.70 | ??????? |
|  2 | 3238 |   3240 | 2020-07-14 08:35:01 |      1 | 192.168.8.70 | ??????? |
|  3 | 3287 |   3240 | 2020-07-15 08:23:24 |      1 | 192.168.8.70 | ??????? |
+----+------+--------+---------------------+--------+--------------+---------+
3 rows in set (0.00 sec)

mysql> begin
    -> ;
Query OK, 0 rows affected (0.00 sec)

mysql> 
mysql> select * from auth_operation where id < 3 for update;
+----+------+--------+---------------------+--------+--------------+---------+
| id | uid  | op_uid | cr_time             | action | address      | remark  |
+----+------+--------+---------------------+--------+--------------+---------+
|  1 | 3278 |   3240 | 2020-07-11 14:44:37 |      1 | 192.168.8.70 | ??????? |
|  2 | 3238 |   3240 | 2020-07-14 08:35:01 |      1 | 192.168.8.70 | ??????? |
+----+------+--------+---------------------+--------+--------------+---------+
2 rows in set (0.00 sec)

首先开启一个会话A,开启事务后查询,锁定了小于3的所有记录,然后在另外一个会话B中执行

mysql> begin;
Query OK, 0 rows affected (0.00 sec) 
mysql> insert into auth_operation (id,uid,op_uid,cr_time,action,address) values
(4,3240,3240,'2020-07-14 08:35:01',1,'127.0.0.1')
    -> ;
Query OK, 1 row affected (0.00 sec)
mysql> 
mysql> 
mysql> insert into auth_operation (id,uid,op_uid,cr_time,action,address) values
(2,3240,3240,'2020-07-14 08:35:01',1,'127.0.0.1')                                    
    -> ;
ERROR 1205 (HY000): Lock wait timeout exceeded; try restarting transaction

我们看到插入数据id=4的时候是成功的,但是插入数据2的时候等待了60秒,报错,是因为在等待会话A释放这个资源,然后等待产生了超时,但是在超时后在select操作会发现,id=4是存在的

mysql>  select * from auth_operation;
+----+------+--------+---------------------+--------+--------------+---------+
| id | uid  | op_uid | cr_time             | action | address      | remark  |
+----+------+--------+---------------------+--------+--------------+---------+
|  1 | 3278 |   3240 | 2020-07-11 14:44:37 |      1 | 192.168.8.70 | ??????? |
|  2 | 3238 |   3240 | 2020-07-14 08:35:01 |      1 | 192.168.8.70 | ??????? |
|  3 | 3287 |   3240 | 2020-07-15 08:23:24 |      1 | 192.168.8.70 | ??????? |
|  4 | 3240 |   3240 | 2020-07-14 08:35:01 |      1 | 127.0.0.1    | NULL    |
+----+------+--------+---------------------+--------+--------------+---------+
4 rows in set (0.00 sec)

这是因为这时会话B中事务虽然抛出了异常,但是既没有进行commit 操作,也没有进行ROLLBACK,这种情况下很不安全(因为InnoDB引擎并不会对异常进行回滚),因此我们通常要在代码里面判断是commit ,还是ROLLBACK,再进行下一步操作!

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值