第 8 章 DCL (Data Control Language)

本文涉及的产品
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
RDS MySQL Serverless 高可用系列,价值2615元额度,1个月
简介:

目录

8.1. 锁
8.1.1. 共享锁
8.1.2. 排他锁
8.1.3. 锁
8.1.3.1. 表的加锁与解锁
8.1.3.2. 禁止查询
8.1.4. 锁等待与超时
8.1.4.1. 超时设置
8.1.4.2. select for update nowait
8.2. 事务处理和锁定语句
8.2.1. 事务隔离级别
8.2.2. 事务所用到的表
8.2.3. 解决更新冲突
8.2.4. SAVEPOINT
COMMIT - save work done
SAVEPOINT - identify a point in a transaction to which you can later roll back
ROLLBACK - restore database to original since the last COMMIT
SET TRANSACTION - Change transaction options like what rollback segment to use
	

8.1. 锁

锁机制

    1) 共享锁:由读表操作加上的锁,加锁后其他用户只能获取该表或行的共享锁,不能获取排它锁,也就是说只能读不能写
    2) 排它锁:由写表操作加上的锁,加锁后其他用户不能获取该表或行的任何锁,典型是mysql事务中的

    锁的范围:
    行锁: 对某行记录加上锁
    表锁: 对整个表加上锁
	

共享锁(share mode), 排他锁(for update)

8.1.1. 共享锁

8.1.2. 排他锁

下面做作一个实验,验证锁的效果

终端一,首先进入事务状态然后运行下面语句

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

mysql> select * from t1 where id='3' for update;
+----+--------+---------------------+---------------------+
| id | name   | ctime               | mtime               |
+----+--------+---------------------+---------------------+
|  3 | test   | 0000-00-00 00:00:00 | 2013-01-14 13:05:41 |
+----+--------+---------------------+---------------------+
1 row in set (0.00 sec)
		
		

终端二, 查询表中数据

		
mysql> select * from t1;
+----+--------+---------------------+---------------------+
| id | name   | ctime               | mtime               |
+----+--------+---------------------+---------------------+
|  1 | neo    | 0000-00-00 00:00:00 | 2013-01-14 13:00:00 |
|  2 | zen    | 0000-00-00 00:00:00 | 2013-01-14 13:00:43 |
|  3 | test   | 0000-00-00 00:00:00 | 2013-01-14 13:05:41 |
+----+--------+---------------------+---------------------+
3 rows in set (0.00 sec)
		
		

增加“for update”查询非锁定记录

		
mysql> select * from t1 where id=2 for update;
+----+------+---------------------+---------------------+
| id | name | ctime               | mtime               |
+----+------+---------------------+---------------------+
|  2 | zen  | 0000-00-00 00:00:00 | 2013-01-14 13:00:43 |
+----+------+---------------------+---------------------+
1 row in set (0.00 sec)
		
		

查询被锁定记录

		
mysql> select * from t1 where id=3 for update;
ERROR 1205 (HY000): Lock wait timeout exceeded; try restarting transaction
		
		

查询所有记录,因为记录中包含了id=3那条,所以也不允许查询。

		
mysql> select * from t1 for update;
ERROR 1205 (HY000): Lock wait timeout exceeded; try restarting transaction
		
		

测试修改记录

		
mysql> UPDATE `t1` SET `name`='testaa' WHERE  `id`=3;
ERROR 1205 (HY000): Lock wait timeout exceeded; try restarting transaction
		
		
[提示] 提示

在没有出现ERROR 1205 (HY000)的这段时间,只要终端一中执行commit,rollback锁就释放了.终端二中的语句就会运行。

select trx_query from information_schema.innodb_trx; 可以查看被锁的SQL语句

8.1.3. 锁

8.1.3.1. 表的加锁与解锁

LOCK TABLES tablename WRITE;
LOCK TABLES tablename READ;

...
...

UNLOCK TABLES;
			
			
CREATE TABLE `locking` (
	`name` VARCHAR(50) NULL DEFAULT NULL
)
ENGINE=InnoDB
;

mysql> insert into locking values('test');
Query OK, 1 row affected (0.02 sec)

mysql> select * from locking;
+------+
| name |
+------+
| test |
+------+
1 row in set (0.00 sec)

mysql> UNLOCK TABLES;
			
			
			

mysql> LOCK TABLES locking READ;
Query OK, 0 rows affected (0.00 sec)

mysql> insert into locking values('test');
ERROR 1099 (HY000): Table 'locking' was locked with a READ lock and can't be updated


mysql> LOCK TABLE locking WRITE;
Query OK, 0 rows affected (0.00 sec)

mysql> select * from locking;
+------+
| name |
+------+
| test |
| test |
+------+
2 rows in set (0.00 sec)

mysql> insert into locking values('test');
Query OK, 1 row affected (0.05 sec)

mysql> UNLOCK TABLES;
			
			

8.1.3.2. 禁止查询

			

mysql> LOCK TABLE locking AS myalias READ;
Query OK, 0 rows affected (0.00 sec)

mysql> select * from locking;
ERROR 1100 (HY000): Table 'locking' was not locked with LOCK TABLES

mysql> select * from locking as myalias;
+------+
| name |
+------+
| test |
| test |
| test |
+------+
3 rows in set (0.00 sec)

			
			

8.1.4. 锁等待与超时

当你开启了事务 begin 忘记,或者各种原因没有commit也没有rollback。悲剧了!

8.1.4.1. 超时设置

begin;
SET SESSION wait_timeout = 60;	
select * from locking for update;
			

60秒内如果没有commit/rollback将自动释放本次事务。

8.1.4.2. select for update nowait

使用 for update 是会遇到一个问题,就是其他用户会漫长的等待,而我们需要程序非阻塞运行,当遇到 for update 的时候应该立即返回此表已被加锁。

mysql 并没有实现 nowait 关键字(类似Oracle的功能),但又一个方法能够达到同样目的。

			
mysql> select @@innodb_version;
+------------------+
| @@innodb_version |
+------------------+
| 5.6.24           |
+------------------+
1 row in set (0.05 sec)
			
mysql> select * from locking;
ERROR 1100 (HY000): Table 'locking' was not locked with LOCK TABLES
			
			

此时需要等待很长时间才能提示 “Table 'locking' was not locked with LOCK TABLES”

			
mysql> set session innodb_lock_wait_timeout=1;
Query OK, 0 rows affected (0.02 sec)

mysql> select * from locking for update;
ERROR 1205 (HY000): Lock wait timeout exceeded; try restarting transaction
			
			

设置 innodb_lock_wait_timeout 参数后,很快就返回

			
mysql> show variables like 'innodb_lock_wait_timeout';
+--------------------------+-------+
| Variable_name            | Value |
+--------------------------+-------+
| innodb_lock_wait_timeout | 1     |
+--------------------------+-------+
1 row in set (0.00 sec)

mysql> show global variables like 'innodb_lock_wait_timeout';
+--------------------------+-------+
| Variable_name            | Value |
+--------------------------+-------+
| innodb_lock_wait_timeout | 50    |
+--------------------------+-------+
1 row in set (0.00 sec)	
			
			

innodb_lock_wait_timeout 默认值是 50





原文出处:Netkiller 系列 手札
本文作者:陈景峯
转载请与作者联系,同时请务必标明文章原始出处和作者信息及本声明。

相关实践学习
基于CentOS快速搭建LAMP环境
本教程介绍如何搭建LAMP环境,其中LAMP分别代表Linux、Apache、MySQL和PHP。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助     相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
目录
相关文章
|
2天前
|
SQL 数据库 数据库管理
什么是 Data Manipulation Language 即 DML
什么是 Data Manipulation Language 即 DML
13 2
|
9月前
|
开发框架 .NET C#
Language Integrated Query
欢迎来到本篇LINQ教程,本文介绍了如何使用C#中的LINQ(Language Integrated Query)。LINQ是C#中的功能,可用于从集合中检索,过滤和操作数据。
55 0
SAP VLPOD 报错 - Update control of movement type is incorrect (entry 107 X X E B _ E) - 之对策
SAP VLPOD 报错 - Update control of movement type is incorrect (entry 107 X X E B _ E) - 之对策
SAP VLPOD 报错 - Update control of movement type is incorrect (entry 107 X X E B _ E) - 之对策
How SAP concrete schema id is got based on transaction type plus catalog type
How SAP concrete schema id is got based on transaction type plus catalog type
101 0
How SAP concrete schema id is got based on transaction type plus catalog type
How does ABAP check table work
Created by Wang, Jerry, last modified on Jan 06, 2017
100 0
How does ABAP check table work
|
计算机视觉
How do you create a DynamicResourceBinding that supports Converters, StringFormat?
原文 How do you create a DynamicResourceBinding that supports Converters, StringFormat? 2 down vote accepted In the past I've resorted to using se...
890 0
|
存储 SQL 关系型数据库
|
存储 SQL 关系型数据库