环境:mysql 5.5.44
存储引擎为:InnoDB
1查看环境
1.1查看数据库参数:
- 数据库版本
Welcome to the MySQL monitor. Commands end with ; or \g. Your MySQL connection id is 8 Server version: 5.5.44 MySQL Community Server (GPL) Copyright (c) 2000, 2015, Oracle and/or its affiliates. All rights reserved. Oracle is a registered trademark of Oracle Corporation and/or its affiliates. Other names may be trademarks of their respective owners. Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
- 存储引擎
mysql> SHOW VARIABLES LIKE 'storage_engine'; +----------------+--------+ | Variable_name | Value | +----------------+--------+ | storage_engine | InnoDB | +----------------+--------+ 1 row in set (0.00 sec)
- 查看下autocommit的值
mysql> select @@autocommit; +--------------+ | @@autocommit | +--------------+ | 1 | +--------------+ 1 row in set (0.00 sec)
- 查看数据库的隔离级别
mysql> select @@tx_isolation; +-----------------+ | @@tx_isolation | +-----------------+ | REPEATABLE-READ | +-----------------+ 1 row in set (0.00 sec)
-
当前运行的所有事务
mysql> select * from information_schema.innodb_trx; Empty set (0.00 sec)
- 当前出现的锁
mysql> select * from information_schema.innodb_locks; Empty set (0.00 sec) mysql> select ENGINE_TRANSACTION_ID, OBJECT_SCHEMA,OBJECT_NAME,INDEX_NAME, LOCK_TYPE,LOCK_MODE, LOCK_STATUS, LOCK_DATA from performance_schema.data_locks;
- 锁等待的对应关系
mysql> select * from information_schema.innodb_lock_waits; Empty set (0.00 sec)
- 查看当前数据库的线程
mysql> show full processlist; +----+------+-----------+----------------+---------+------+-------+-----------------------+ | Id | User | Host | db | Command | Time | State | Info | +----+------+-----------+----------------+---------+------+-------+-----------------------+ | 8 | root | localhost | smarterbanking | Sleep | 1592 | | NULL | | 9 | root | localhost | smarterbanking | Sleep | 1502 | | NULL | | 11 | root | localhost | smarterbanking | Query | 0 | NULL | show full processlist | +----+------+-----------+----------------+---------+------+-------+-----------------------+ 3 rows in set (0.00 sec)
1.2 查看测试表 t100_codeinfo信息
- 查看元数据信息
mysql> SELECT * FROM information_schema.tables WHERE table_schema='smarterbanking' AND table_name='t100_codeinfo'; +---------------+----------------+---------------+------------+--------+---------+------------+------------+----------------+-------------+-----------------+--------------+-----------+----------------+---------------------+-------------+------------+-----------------+----------+----------------+---------------+ | TABLE_CATALOG | TABLE_SCHEMA | TABLE_NAME | TABLE_TYPE | ENGINE | VERSION | ROW_FORMAT | TABLE_ROWS | AVG_ROW_LENGTH | DATA_LENGTH | MAX_DATA_LENGTH | INDEX_LENGTH | DATA_FREE | AUTO_INCREMENT | CREATE_TIME | UPDATE_TIME | CHECK_TIME | TABLE_COLLATION | CHECKSUM | CREATE_OPTIONS | TABLE_COMMENT | +---------------+----------------+---------------+------------+--------+---------+------------+------------+----------------+-------------+-----------------+--------------+-----------+----------------+---------------------+-------------+------------+-----------------+----------+----------------+---------------+ | def | smarterbanking | t100_codeinfo | BASE TABLE | InnoDB | 10 | Compact | 57 | 287 | 16384 | 0 | 0 | 4194304 | NULL | 2020-06-12 00:29:06 | NULL | NULL | utf8_general_ci | NULL | | | +---------------+----------------+---------------+------------+--------+---------+------------+------------+----------------+-------------+-----------------+--------------+-----------+----------------+---------------------+-------------+------------+-----------------+----------+----------------+---------------+ 1 row in set (0.00 sec)
- 查看表结构
mysql> desc t100_codeinfo; +-----------------+--------------+------+-----+---------+-------+ | Field | Type | Null | Key | Default | Extra | +-----------------+--------------+------+-----+---------+-------+ | f_categoryno | varchar(64) | NO | PRI | NULL | | | f_codeno | varchar(64) | NO | PRI | NULL | | | f_codevalue | varchar(64) | NO | | NULL | | | f_desc | varchar(64) | YES | | NULL | | | f_categoryflag | bit(1) | NO | | NULL | | | f_availableflag | bit(1) | NO | | b'0' | | | f_field1 | varchar(255) | YES | | NULL | | | f_field2 | varchar(255) | YES | | NULL | | +-----------------+--------------+------+-----+---------+-------+ 8 rows in set (0.00 sec)
2 测试
数据内容
mysql> select * from t100_codeinfo;
+--------------+-------------------------------------+--------------------------------------------+--------------------------------------------------------------------------+----------------+-----------------+----------------+----------+
| f_categoryno | f_codeno | f_codevalue | f_desc | f_categoryflag | f_availableflag | f_field1 | f_field2 |
+--------------+-------------------------------------+--------------------------------------------+--------------------------------------------------------------------------+----------------+-----------------+----------------+----------+
| ## | ACTION | 应用操作日志 | | | | NULL | NULL |
| ## | ALT | 应用日志类型 | NULL | | | NULL | NULL |
| ## | AT | 应用类型 | NULL | | | NULL | NULL |
| ## | DT | 设备类型 | NULL | | | NULL | NULL |
| ## | NODETYPE | 节点类型 | | | | NULL | NULL |
| ## | PROPERTY | 资源属性 | NULL | | | NULL | NULL |
| ## | PROTYPE | 资源类型 | | | | NULL | NULL |
| ACTION | ACTION001 | 业务兑换 | 售卖机使用 | | | this is a test | NULL |
| ACTION | ACTION002 | 二维码兑换 | 售卖机专用 | | | this is a test | NULL |
| ACTION | ACTION003 | 现金购买 | 售卖机专用 | | | this is a test | NULL |
| ACTION | ACTION004 | 刷卡购买 | 售卖机专用 | | | this is a test | NULL |
| ACTION | ACTION005 | 大转盘游戏获奖 | 体感专用 | | | this is a test | NULL |
| ACTION | ACTION008 | 接金币游戏获奖 | 体感专用 | | | this is a test | NULL |
| ACTION | ACTION013 | 有奖问答获奖 | 体感专用 | | | this is a test | NULL |
| ALT | AL001 | 应用启动 | | | | NULL | NULL |
| ALT | AL002 | 应用退出 | | | | NULL | NULL |
| ALT | AL003 | 应用更新检测 | | | | NULL | NULL |
| ALT | AL004 | 应用更新 | | | | NULL | NULL |
| ALT | AL005 | 应用删除 | | | | NULL | NULL |
| AT | APP001 | 体感 | | | | NULL | NULL |
| AT | APP002 | 电子橱窗(有体感功能) | | | | NULL | NULL |
| AT | APP003 | 电子海报 | | | | NULL | NULL |
| AT | APP004 | 虚拟引导 | | | | NULL | NULL |
| AT | APP005 | 智能茶几 | | | | NULL | NULL |
| AT | APP007 | 售卖机程序 | | | | NULL | NULL |
| AT | APP100 | Windows客户端 | | | | NULL | NULL |
| AT | APP501 | 安卓大转盘 | 熊猫专用 | | | NULL | NULL |
| AT | APPMODULE101 | 体感问答模块 | | | | NULL | NULL |
| DT | DEV001 | 三星GALAXY Tab S T805C | 用于叫号显示、高存和VTM室状态显示、理财室叫号显示 | | | NULL | NULL |
| DT | DEV002 | 联想一体机A740 | 主要用于虚拟引导使用 | | | NULL | NULL |
| DT | DEV003 | 体感大屏(全套) | | | | NULL | NULL |
| DT | DEV004 | 电子橱窗 | | | | NULL | NULL |
| DT | DEV005 | 电子海报 | | | | NULL | NULL |
| DT | DEV006 | 智能茶几 | | | | NULL | NULL |
| DT | DEV007 | 售卖机(中吉) | | | | NULL | NULL |
| NODETYPE | award-winning_question | 有奖问答 | | | | NULL | NULL |
| NODETYPE | motionsensingdirnode | 体感目录节点 | | | | NULL | NULL |
| NODETYPE | motionsensingleafnode | 体感叶子节点 | | | | NULL | NULL |
| NODETYPE | motionsensingleafnodeForVideo | 体感叶子视频节点 | | | | NULL | NULL |
| NODETYPE | smarterbankingteapoy | 智能茶几节点 | | | | NULL | NULL |
| NODETYPE | testnode | 测试节点 | | | | NULL | NULL |
| NODETYPE | TurntableGameWinningProbabilityNode | 安卓大转盘中奖概率节点 | | | | NULL | NULL |
| PROPERTY | desc | 描述 | | | | NULL | NULL |
| PROPERTY | filetype | 文件格式 | | | | NULL | NULL |
| PROPERTY | height | 高度(视频或图片的高度) | 单位:px | | | NULL | NULL |
| PROPERTY | length | 时长(视频或音频文件的时长) | | | | NULL | NULL |
| PROPERTY | path | 文件的访问路径 | | | | NULL | NULL |
| PROPERTY | URL | 文件的URL地址 | | | | NULL | NULL |
| PROPERTY | value | 字符串的值 | | | | NULL | NULL |
| PROPERTY | width | 宽度(视频或图片的宽度) | 单位:px | | | NULL | NULL |
| PROTYPE | file | 单文件 | 普通文件 | | | NULL | NULL |
| PROTYPE | picture | 单图片 | | | | NULL | NULL |
| PROTYPE | pictures | 多文件 | 图片视频文件等 | | | NULL | NULL |
| PROTYPE | string | 字符串 | | | | NULL | NULL |
| PROTYPE | video | 单视频 | | | | NULL | NULL |
| test01 | test01 | test01 | | | | NULL | NULL |
| test02 | test02 | test02 | | | | NULL | NULL |
+--------------+-------------------------------------+--------------------------------------------+--------------------------------------------------------------------------+----------------+-----------------+----------------+----------+
57 rows in set (0.00 sec)
2.1 事务1上锁行
-
在事务1中,以 f_categoryno="ACTION" and f_codeno="ACTION001" 为条件对t100_codeinfo进行上锁
mysql> start transaction; Query OK, 0 rows affected (0.00 sec) mysql> select * from t100_codeinfo where f_categoryno="ACTION" and f_codeno="ACTION001" for update; +--------------+-----------+--------------+-----------------+----------------+-----------------+----------------+----------+ | f_categoryno | f_codeno | f_codevalue | f_desc | f_categoryflag | f_availableflag | f_field1 | f_field2 | +--------------+-----------+--------------+-----------------+----------------+-----------------+----------------+----------+ | ACTION | ACTION001 | 业务兑换 | 售卖机使用 | | | this is a test | NULL | +--------------+-----------+--------------+-----------------+----------------+-----------------+----------------+----------+ 1 row in set (0.00 sec)
-
test01: 在事务2中,以同样的条件( f_categoryno="ACTION" and f_codeno="ACTION001" )对t100_codeinfo进行上锁
事务2 状态从等锁到等锁失败mysql> start transaction; Query OK, 0 rows affected (0.00 sec) mysql> select * from t100_codeinfo where f_categoryno="ACTION" and f_codeno="ACTION001" for update; ERROR 1205 (HY000): Lock wait timeout exceeded; try restarting transaction
test02:在事务2中,以包含条件( f_categoryno="ACTION" )对t100_codeinfo进行上锁
事务2 状态从等锁到等锁失败mysql> select * from t100_codeinfo where f_categoryno="ACTION" for update; ERROR 1205 (HY000): Lock wait timeout exceeded; try restarting transaction
test03:在事务2中,以其他条件(f_categoryno="DT" and f_codeno="DEV002")对t100_codeinfo进行上锁
事务2 上锁成功mysql> select * from t100_codeinfo where f_categoryno="DT" and f_codeno="DEV002" for update; +--------------+----------+---------------------+--------------------------------+----------------+-----------------+----------+----------+ | f_categoryno | f_codeno | f_codevalue | f_desc | f_categoryflag | f_availableflag | f_field1 | f_field2 | +--------------+----------+---------------------+--------------------------------+----------------+-----------------+----------+----------+ | DT | DEV002 | 联想一体机A740 | 主要用于虚拟引导使用 | | | NULL | NULL | +--------------+----------+---------------------+--------------------------------+----------------+-----------------+----------+----------+ 1 row in set (0.00 sec)
test04:在事务2中,以其他条件(f_categoryno="ACTION2222")对进行 空行上锁
事务2上锁成功mysql> select * from t100_codeinfo where f_categoryno="ACTION2222" for update; Empty set (0.00 sec)
事务1可以写数据,但不可以写入符合事务2锁定条件的数据,表没有被锁定
mysql> INSERT INTO `t100_codeinfo` VALUES ('ACTION2222', 'ACTION2222', 'test_0005', 'test_0005', '\0', '', null, null); ERROR 1205 (HY000): Lock wait timeout exceeded; try restarting transaction mysql> INSERT INTO `t100_codeinfo` VALUES ('test_ACVdddddd', 'test_0005_abcddd', 'test_0005', 'test_0005', '\0', '', null, null); Query OK, 1 row affected (0.00 sec)
-
事务2 等锁时,查看事务信息,上锁信息,上锁等待信息
mysql> select * from information_schema.innodb_trx; +--------+-----------+---------------------+-----------------------+---------------------+------------+---------------------+---------------------------------------------------------------------------------------------+---------------------+-------------------+-------------------+------------------+-----------------------+-----------------+-------------------+-------------------------+---------------------+-------------------+------------------------+----------------------------+---------------------------+---------------------------+ | trx_id | trx_state | trx_started | trx_requested_lock_id | trx_wait_started | trx_weight | trx_mysql_thread_id | trx_query | trx_operation_state | trx_tables_in_use | trx_tables_locked | trx_lock_structs | trx_lock_memory_bytes | trx_rows_locked | trx_rows_modified | trx_concurrency_tickets | trx_isolation_level | trx_unique_checks | trx_foreign_key_checks | trx_last_foreign_key_error | trx_adaptive_hash_latched | trx_adaptive_hash_timeout | +--------+-----------+---------------------+-----------------------+---------------------+------------+---------------------+---------------------------------------------------------------------------------------------+---------------------+-------------------+-------------------+------------------+-----------------------+-----------------+-------------------+-------------------------+---------------------+-------------------+------------------------+----------------------------+---------------------------+---------------------------+ | 9A13 | LOCK WAIT | 2020-06-12 10:54:01 | 9A13:0:647:9 | 2020-06-12 10:58:06 | 2 | 12 | select * from t100_codeinfo where f_categoryno="ACTION" and f_codeno="ACTION001" for update | starting index read | 1 | 1 | 2 | 376 | 1 | 0 | 0 | REPEATABLE READ | 1 | 1 | NULL | 0 | 10000 | | 9A12 | RUNNING | 2020-06-12 10:53:29 | NULL | NULL | 2 | 11 | NULL | NULL | 0 | 0 | 2 | 376 | 1 | 0 | 0 | REPEATABLE READ | 1 | 1 | NULL | 0 | 10000 | +--------+-----------+---------------------+-----------------------+---------------------+------------+---------------------+---------------------------------------------------------------------------------------------+---------------------+-------------------+-------------------+------------------+-----------------------+-----------------+-------------------+-------------------------+---------------------+-------------------+------------------------+----------------------------+---------------------------+---------------------------+ 2 rows in set (0.00 sec) mysql> 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 | +--------------+-------------+-----------+-----------+----------------------------------+------------+------------+-----------+----------+-----------------------+ | 9A13:0:647:9 | 9A13 | X | RECORD | `smarterbanking`.`t100_codeinfo` | `PRIMARY` | 0 | 647 | 9 | 'ACTION', 'ACTION001' | | 9A12:0:647:9 | 9A12 | X | RECORD | `smarterbanking`.`t100_codeinfo` | `PRIMARY` | 0 | 647 | 9 | 'ACTION', 'ACTION001' | +--------------+-------------+-----------+-----------+----------------------------------+------------+------------+-----------+----------+-----------------------+ 2 rows in set (0.00 sec) mysql> select * from information_schema.innodb_lock_waits; +-------------------+-------------------+-----------------+------------------+ | requesting_trx_id | requested_lock_id | blocking_trx_id | blocking_lock_id | +-------------------+-------------------+-----------------+------------------+ | 9A13 | 9A13:0:647:9 | 9A12 | 9A12:0:647:9 | +-------------------+-------------------+-----------------+------------------+ 1 row in set (0.01 sec)
-
事务2 等锁失败,查看事务信息,上锁信息,上锁等待信息
mysql> select * from information_schema.innodb_trx; +--------+-----------+---------------------+-----------------------+------------------+------------+---------------------+-----------+---------------------+-------------------+-------------------+------------------+-----------------------+-----------------+-------------------+-------------------------+---------------------+-------------------+------------------------+----------------------------+---------------------------+---------------------------+ | trx_id | trx_state | trx_started | trx_requested_lock_id | trx_wait_started | trx_weight | trx_mysql_thread_id | trx_query | trx_operation_state | trx_tables_in_use | trx_tables_locked | trx_lock_structs | trx_lock_memory_bytes | trx_rows_locked | trx_rows_modified | trx_concurrency_tickets | trx_isolation_level | trx_unique_checks | trx_foreign_key_checks | trx_last_foreign_key_error | trx_adaptive_hash_latched | trx_adaptive_hash_timeout | +--------+-----------+---------------------+-----------------------+------------------+------------+---------------------+-----------+---------------------+-------------------+-------------------+------------------+-----------------------+-----------------+-------------------+-------------------------+---------------------+-------------------+------------------------+----------------------------+---------------------------+---------------------------+ | 9A13 | RUNNING | 2020-06-12 10:54:01 | NULL | NULL | 1 | 12 | NULL | NULL | 0 | 0 | 1 | 376 | 0 | 0 | 0 | REPEATABLE READ | 1 | 1 | NULL | 0 | 10000 | | 9A12 | RUNNING | 2020-06-12 10:53:29 | NULL | NULL | 2 | 11 | NULL | NULL | 0 | 0 | 2 | 376 | 1 | 0 | 0 | REPEATABLE READ | 1 | 1 | NULL | 0 | 10000 | +--------+-----------+---------------------+-----------------------+------------------+------------+---------------------+-----------+---------------------+-------------------+-------------------+------------------+-----------------------+-----------------+-------------------+-------------------------+---------------------+-------------------+------------------------+----------------------------+---------------------------+---------------------------+ 2 rows in set (0.00 sec) mysql> select * from information_schema.innodb_locks; Empty set (0.00 sec) mysql> select * from information_schema.innodb_lock_waits; Empty set (0.00 sec)
-
结论:
1)事务1 获取的是一个行排他锁
2)在当前的隔离级别下,被终端1 锁定的数据可被其他事务读取(不可增删改)mysql> select * from t100_codeinfo where f_categoryno="ACTION" and f_codeno="ACTION001"; +--------------+-----------+--------------+-----------------+----------------+-----------------+----------------+----------+ | f_categoryno | f_codeno | f_codevalue | f_desc | f_categoryflag | f_availableflag | f_field1 | f_field2 | +--------------+-----------+--------------+-----------------+----------------+-----------------+----------------+----------+ | ACTION | ACTION001 | 业务兑换 | 售卖机使用 | | | this is a test | NULL | +--------------+-----------+--------------+-----------------+----------------+-----------------+----------------+----------+ 1 row in set (0.00 sec)
2.4 事务1和事务2上锁空行
- 关闭所有事务
mysql> select * from information_schema.innodb_trx; Empty set (0.00 sec) mysql> select * from information_schema.innodb_locks; Empty set (0.00 sec) mysql> select * from information_schema.innodb_lock_waits; Empty set (0.00 sec)
- 事务1 锁定空行
mysql> start transaction; Query OK, 0 rows affected (0.00 sec) mysql> select * from t100_codeinfo where f_categoryno="test_0001" and f_codeno="test_0001" for update; Empty set (0.00 sec) mysql> select * from information_schema.innodb_trx; +--------+-----------+---------------------+-----------------------+------------------+------------+---------------------+---------------------------------------------+---------------------+-------------------+-------------------+------------------+-----------------------+-----------------+-------------------+-------------------------+---------------------+-------------------+------------------------+----------------------------+---------------------------+---------------------------+ | trx_id | trx_state | trx_started | trx_requested_lock_id | trx_wait_started | trx_weight | trx_mysql_thread_id | trx_query | trx_operation_state | trx_tables_in_use | trx_tables_locked | trx_lock_structs | trx_lock_memory_bytes | trx_rows_locked | trx_rows_modified | trx_concurrency_tickets | trx_isolation_level | trx_unique_checks | trx_foreign_key_checks | trx_last_foreign_key_error | trx_adaptive_hash_latched | trx_adaptive_hash_timeout | +--------+-----------+---------------------+-----------------------+------------------+------------+---------------------+---------------------------------------------+---------------------+-------------------+-------------------+------------------+-----------------------+-----------------+-------------------+-------------------------+---------------------+-------------------+------------------------+----------------------------+---------------------------+---------------------------+ | 9E00 | RUNNING | 2020-06-12 11:42:49 | NULL | NULL | 2 | 2 | select * from information_schema.innodb_trx | NULL | 0 | 0 | 2 | 376 | 1 | 0 | 0 | REPEATABLE READ | 1 | 1 | NULL | 0 | 10000 | +--------+-----------+---------------------+-----------------------+------------------+------------+---------------------+---------------------------------------------+---------------------+-------------------+-------------------+------------------+-----------------------+-----------------+-------------------+-------------------------+---------------------+-------------------+------------------------+----------------------------+---------------------------+---------------------------+ 1 row in set (0.00 sec)
- 事务2锁定空行,则表被锁定
mysql> INSERT INTO `t100_codeinfo` VALUES ('test_0001', 'test_0001', 'test_0001', 'test_0001', '\0', '', null, null); ERROR 1205 (HY000): Lock wait timeout exceeded; try restarting transaction mysql> INSERT INTO `t100_codeinfo` VALUES ('test_123456', 'test_123456', 'test_123456', 'test_123', '\0', '', null, null); ERROR 1205 (HY000): Lock wait timeout exceeded; try restarting transaction
- 结论:
如果两个事务同时锁定了空行,就锁定了整张表。事务1,事务2及其他事务3 都无法写入数据
2.5 空表测试(t100_codeinfo无数据)
和空行测试结果一致