mysql事务未提交导致锁等待如何解决

1、实验环境

Myql版本5.7.17-log

实验表结构

([email protected])[apex]> show create table test;
+-------+-----------------------------------------------------------------------------------------------------------------------------------+
| Table| Create Table                                                                                                                     |
+-------+-----------------------------------------------------------------------------------------------------------------------------------+
|test  | CREATE TABLE `test` (
  `x` int(11) NOT NULL,
  `y` int(11) DEFAULT NULL,
  PRIMARY KEY (`x`)
)ENGINE=InnoDB DEFAULT CHARSET=gbk |
+-------+-----------------------------------------------------------------------------------------------------------------------------------+
1 row inset (0.01 sec)

插入数据

([email protected])[apex]> insert into test values(1,1);
([email protected])[apex]> insert into test values(2,2);
([email protected])[apex]> insert into test values(3,3);

2、锁产生步骤

会话一:开启事务,更新数据,不提交

([email protected])[apex]> begin;
QueryOK, 0 rows affected (0.00 sec)
([email protected])[apex]> update test set y=y+1 where x=1;
QueryOK, 1 row affected (0.00 sec)
Rowsmatched: 1  Changed: 1  Warnings: 0

查看当前连接id号(线程id号)

([email protected])[apex]> select connection_id();
+-----------------+
|connection_id() |
+-----------------+
|               4 |
+-----------------+
1 row inset (0.00 sec)

会话二:开启另一个事务,更新同一行数据,

([email protected])[apex]> begin;
QueryOK, 0 rows affected (0.00 sec)
 
([email protected])[apex]> update test set y=y+1 where x=1;
ERROR1205 (HY000): Lock wait timeout exceeded; try restarting transaction

执行update test set操作时,会卡在那边,不执行,经过50秒后,会报错;

(上面的卡住现象,是由于锁,可以通过查看表information_schema.innodb_lock,获取锁的状态)

([email protected])[information_schema]> select * from information_schema.innodb_locks;
+-----------------+-------------+-----------+-----------+---------------+------------+------------+-----------+----------+-----------+
|lock_id         | lock_trx_id | lock_mode| lock_type | lock_table    | lock_index| lock_space | lock_page | lock_rec | lock_data |
+-----------------+-------------+-----------+-----------+---------------+------------+------------+-----------+----------+-----------+
|757082:3279:3:2 | 757082      | X         | RECORD    | `apex`.`test` | PRIMARY    |      3279 |         3 |       2 | 1         |
|757081:3279:3:2 | 757081      | X         | RECORD    | `apex`.`test` | PRIMARY    |      3279 |         3 |        2 | 1         |
+-----------------+-------------+-----------+-----------+---------------+------------+------------+-----------+----------+-----------+
2 rowsin set, 1 warning (0.00 sec)

查看当前连接id号(线程id号)

 ([email protected]) [apex]> selectconnection_id();
+-----------------+
|connection_id() |
+-----------------+
|               5 |
+-----------------+
1 row inset (0.00 sec)

以上说的50秒,是系统参数innodb_lock_wait_timeout决定的

([email protected])[apex]> show variables like ‘innodb_lock_wait_timeout‘;
+--------------------------+-------+
|Variable_name            | Value |
+--------------------------+-------+
| innodb_lock_wait_timeout|  50  |
+--------------------------+-------+
1 row inset (0.00 sec)

3、mysql 如何查看未提交的事务

方法一:

([email protected])[performance_schema]>  SELECT * FROMinformation_schema.INNODB_TRX\G
***************************1. row ***************************
                    trx_id: 756996
                 trx_state: RUNNING
               trx_started: 2017-05-08 15:08:07
     trx_requested_lock_id: NULL
          trx_wait_started: NULL
                trx_weight: 3
       trx_mysql_thread_id: 4
                 trx_query: NULL
       trx_operation_state: NULL
         trx_tables_in_use: 0
         trx_tables_locked: 1
          trx_lock_structs: 2
     trx_lock_memory_bytes: 1136
           trx_rows_locked: 1
         trx_rows_modified: 1
   trx_concurrency_tickets: 0
       trx_isolation_level: REPEATABLE READ
         trx_unique_checks: 1
    trx_foreign_key_checks: 1
trx_last_foreign_key_error:NULL
 trx_adaptive_hash_latched: 0
 trx_adaptive_hash_timeout: 0
          trx_is_read_only: 0
trx_autocommit_non_locking:0
1 row inset (0.00 sec)

通过以上可看出线程id为4 一直未提交,事务开始的时间为2017-05-08 15:08:07。

方法二:通过 show engine innodb status\G

其中有一段关于事务的描述

TRANSACTIONS
------------
Trx idcounter 756998
Purgedone for trx‘s n:o < 0 undo n:o < 0 state: running but idle
Historylist length 0
LIST OFTRANSACTIONS FOR EACH SESSION:
---TRANSACTION421519065333360, not started
0 lockstruct(s), heap size 1136, 0 row lock(s)
---TRANSACTION421519065332448, not started
0 lockstruct(s), heap size 1136, 0 row lock(s)
---TRANSACTION756996, ACTIVE 914 sec
2 lockstruct(s), heap size 1136, 1 row lock(s), undo log entries 1
MySQL thread id 4, OS thread handle 140041791522560, query id25 localhost root

从以上也可以看出线程id号为4的事务一直未提交。

4、如何解决未提交的事务

方法一:如果能知道哪个用户在执行这个操作,让他提交一下(这种可能性很小)

方法二:kill掉这个线程id号,让事务回滚,

([email protected])[information_schema]> show processlist;
+----+-----------------+------------------+--------------------+---------+------+------------------------+------------------+
| Id |User            | Host             | db                 | Command | Time | State                  | Info             |
+----+-----------------+------------------+--------------------+---------+------+------------------------+------------------+
|  1 | event_scheduler | localhost        | NULL               | Daemon  | 4469 | Waiting on empty queue | NULL             |
|  4 | root            | localhost        | apex               | Sleep   |  871|                        | NULL             |
|  5 | root            | localhost        | apex               | Sleep   |   82|                        | NULL             |
|  6 | root            | localhost        | information_schema | Query   |    0| starting               | showprocesslist |
|  7 | root            | 192.168.1.1:3708 | NULL               | Sleep   | 3221 |                        | NULL             |
+----+-----------------+------------------+--------------------+---------+------+------------------------+------------------+
5 rowsin set (0.00 sec)
 
([email protected])[information_schema]> kill 4;
QueryOK, 0 rows affected (0.01 sec)
时间: 2024-10-10 12:56:38

mysql事务未提交导致锁等待如何解决的相关文章

排查MySQL事务没有提交导致 锁等待 Lock wait timeout exceeded

解决思路: select * from information_schema.innodb_trx 之后找到了一个一直没有提交的只读事务, kill 到了对应的线程后ok 了. 转载自:http://blog.sina.com.cn/s/blog_6bb63c9e0100s7cb.html 在Mysql5.5中,information_schema 库中增加了三个关于锁的表(MEMORY引擎): innodb_trx ## 当前运行的所有事务 innodb_locks ## 当前出现的锁 inn

【MySQL】事务没有提交导致 锁等待Lock wait timeout exceeded异常

异常:Lock wait timeout exceeded; try restarting transaction 解决办法:(需要数据库最高权限) 执行select * from information_schema.innodb_trx 之后找到了一个一直没有提交的只读事务, 找到对应的线程后,执行 kill thread id,再确认一直没有提交的只读事物被干掉了就OK了.

Mysql事务并发问题,锁机制

Mysql事务并发问题,锁机制 1.什么是事务 事务是一条或多条数据库操作语句的组合,具备ACID,4个特点. 原子性:要不全部成功,要不全部撤销 隔离性:事务之间相互独立,互不干扰 一致性:数据库正确地改变状态后,数据库的一致性约束没有被破坏 持久性:事务的提交结果,将持久保存在数据库中 2.事务并发会产生什么问题 1)第一类丢失更新:在没有事务隔离的情况下,两个事务都同时更新一行数据,但是第二个事务却中途失败退出, 导致对数据的两个修改都失效了. 例如: 张三的工资为5000,事务A中获取工

SQLServer之创建事务未提交读

未提交读注意事项 使用 SET TRANSACTION ISOLATION LEVEL 指定会话的锁定级别. 一次只能设置一个隔离级别选项,而且设置的选项将一直对那个连接始终有效,直到显式更改该选项为止. 事务中执行的所有读取操作都会在指定的隔离级别的规则下运行,除非语句的 FROM 子句中的表提示为表指定了其他锁定行为或版本控制行为. 事务隔离级别定义了可为读取操作获取的锁类型. 在事务进行期间,可以随时将事务从一个隔离级别切换到另一个隔离级别,但有一种情况例外. 即在从任一隔离级别更改到 S

Mysql事务及行级锁

事务隔离级别 数据库事务隔离级别,只是针对一个事务能不能读取其它事务的中间结果. Read Uncommitted (读取未提交内容) 在该隔离级别,所有事务都可以看到其他未提交事务的执行结果.本隔离级别很少用于实际应用,因为它的性能也不比其他级别好多少.读取未提交的数据,也被称之为脏读( Dirty Read ). Read Committed (读取提交内容) 这是大多数数据库系统的默认隔离级别(但不是 MySQL 默认的).它满足了隔离的简单定义:一个事务只能看见已经提交事务所做的改变.这

Mysql事务及行级锁的理解

在最近的开发中,碰到一个需求签到,每个用户每天只能签到一次,那么怎么去判断某个用户当天是否签到呢?因为当属表设计的时候,每个用户签到一次,即向表中插入一条记录,根据记录的数量和时间来判断用户当天是否签到. 这样的话就会有一个问题,如果是在网速过慢的情况下,用户多次点击签到按钮,那么变会发送多次请求,可能会导致一天多次签到,重复提交的问题,那么很自然的想到用事务.这次用的是spring + mybtais的框架,一开始设计的代码大致如下: public boolean signIn(SignInH

mysql事务隔离界别与锁机制

数据库锁 共享锁(Shared lock) 例1: ---------------------------------------- T1: select * from table (请想象它需要执行1个小时之久,后面的sql语句请都这么想象) T2: update table set column1='hello' 过程:T1运行 (加共享锁) T2运行等待T1运行完之后再运行T2 之所以要等,是因为T2在执行update前,试图对table表加一个排他锁,而数据库规定同一资源上不能同时共存共

理解MySql事务隔离机制、锁以及各种锁协议

一直以来对数据库的事务隔离机制的理解总是停留在表面,其内容也是看一遍忘一边.这两天决定从原理上理解它,整理成自己的知识.查阅资料的过程中发现好多零碎的概念如果串起来足够写一本书,所以在这里给自己梳理一个脉络,具体的内容参考引文或在网上搜一下.由于平时接触最多的是MySQL,所以文章中某些部分是MySQL特有的特性,请读者注意. 数据库并发操作会引发的问题: 多个事务同时访问数据库时候,会发生下列5类问题,包括3类数据读问题(脏读,不可重复读,幻读),2类数据更新问题(第一类丢失更新,第二类丢失更

MySQL事务隔离级别和锁

表结构 create table record( id int auto_increment primary key, title varchar(255) not null, shortName varchar(255) not null, authorId int not null, createTime datetime not null, state int  not null, totalView int default null ); insert into record (titl