配色: 字号:
《MySQL 8.0数据库管理与应用》第7章 事务与锁定
2023-05-25 | 阅:  转:  |  分享 
  
第7章 事务与锁定7.1.1 事务概述事务是指作为单个逻辑工作单元执行的一个或多个SQL语句。如果某一事务成功,则在该事务中进行的所有数
据更改都会提交并成为数据库中的永久组成部分;如果事务遇到错误而且撤销或回滚,则所有数据更改都会被清除。一个逻辑工作单元必须有4个属
性,称为原子性、一致性、隔离性和持久性(ACID)属性,只有这样才能成为一个事务。1. 原子性(A)事务必须是原子工作单元,整个事
务中的所有操作,要么全部执行,要么全部都不执行,不可能停滞在某个中间环节。如果事务在执行过程中发生错误,会被返回到事务开始前的状态
,就像这个事务从来没有执行过一样。2. 一致性(C)当事务完成时,必须使所有的数据都保持一致状态。3. 隔离性(I)由并发事务所做
的修改必须与任何其他并发事务所做的修改隔离。4. 持久性(D)完成完全持久的事务之后,它的影响将永久存在于系统中。7.1 事务7
.1.2 设置自动提交模式默认情况下,MySQL是在启用自动提交模式的情况下运行的。使用SET autocommit语句来禁用或
启用当前会话的默认自动提交模式:SET autocommit={0 | 1}如果将系统变量autocommit设置为1,则对表的所
有更改都会立即生效。如果将该变量设置为0,则禁用自动提交模式。变量autocommit是一个会话变量,必须对每个会话进行设置。默认
情况下,客户端连接将以autocommit设置为1开始。如果要对每个新连接禁用自动提交模式,则需要对全局自动提交值进行设置。使用-
-autocommit=0选项启动MySQL服务器:mysqld --autocommit=0使用MySQL配置文件设置全局变量:
[mysqld]autocommit=07.1 事务7.1.3 开始事务使用START TRANSACTION语句将使自动提交
模式保持禁用状态,一直到使用COMMIT或ROLLBACK语句结束事务,自动提交模式恢复为先前的状态,语法格式如下。START T
RANSACTION[事务特征[, 事务特征] ...]事务特征:{WITH CONSISTENT SNAPSHOT| READ
WRITE | READ ONLY}以BEGIN和BEGIN WORK作为START TRANSACTION的别名来启动事务:BE
GIN [WORK]7.1 事务7.1.4 提交事务使用COMMIT语句可以提交当前事务,使其更改成为永久更改,语法格式如下。
COMMIT [WORK] [AND [NO] CHAIN] [[NO] RELEASE]COMMIT语句支持可选的WORK关键字
,也支持CHAIN和RELEASE子句。CHAIN和RELEASE子句可以用于对事务完成的附加控制。AND CHAIN子句导致新事
务在当前事务结束后立即开始,并且新事务与刚刚终止的事务具有相同的隔离级别。新事务还使用与刚刚终止的事务相同的访问模式(READ W
RITE或READ ONLY)。RELEASE子句使服务器在终止当前事务后断开当前客户端会话。使用NO关键字可以禁止CHAIN或R
ELEASE完成。如果系统变量completion_type默认设置为CHAIN或RELEASE完成,则NO选项是很有用的。7.1
事务7.1.5 回滚事务使用ROLLBACK语句可以回滚当前事务,撤消其更改,语法格式如下。ROLLBACK [WORK]
[AND [NO] CHAIN] [[NO] RELEASE]ROLLBACK语句支持可选的WORK关键字,也支持CHAIN和RE
LEASE子句。CHAIN和RELEASE子句可以用于对事务完成的附加控制,请参阅COMMIT语句中的说明。某些语句是无法回滚的。
这些语句包括数据定义语言(DDL)语句,例如创建或删除数据库的语句,创建、删除或更改表或存储例程的语句。应该将事务设计为不包括这一
类语句。如果在无法回滚的事务的早期发出语句,而以后出现另一个语句失败,则在这种情况下无法通过发出ROLLBACK语句来回滚事务的完
整效果。回滚的事务不会被记录。对非事务性表的修改是无法回滚的。如果回滚的事务包括对非事务性表的修改,则在末尾使用ROLLBACK语
句记录整个事务,以确保复制对非事务性表的修改。7.1 事务7.1.6 事务保存点1. 设置事务保存点SAVEPOINT 保存点
名称如果当前事务具有相同名称的保存点,则删除旧保存点并设置新保存点。2. 回滚到事务保存点ROLLBACK [WORK] TO [
SAVEPOINT] 保存点名称设置保存点后当前事务对行进行的修改在回滚中撤消。如果不存在具有指定名称的保存点,则ROLLBACK
TO SAVEPOINT语句返回错误。3. 删除事务保存点RELEASE SAVEPOINT 保存点名称删除指定的保存点不会发生
提交或回滚事务。如果保存点不存在则会出错。7.1 事务7.1.7 设置事务特征使用SET TRANSACTION语句可以设置事
务的隔离级别和访问模式,语法格式如下。SET [GLOBAL | SESSION] TRANSACTION事务特征[, 事务特征]
...事务特征{ISOLATION LEVEL 隔离级别|READ WRITE|READ ONLY}隔离级别:{REPEATAB
LE READ | READ COMMITTED|READ UNCOMMITTED | SERIALIZABLE}7.1 事务7
.2.1 锁定级别表级锁定 这是一种特殊的锁定,整个表都被用户锁定,其他用户不能向表中插入行,甚至从表中获取数据也会受到限制。M
yISAM表仅支持表级锁定,当涉及大量读操作而不是写操作时,表级锁定提供了优于页行锁定和行级锁定的性能。页级锁定: MySQL锁定
表中的某些行(称为页)。被锁定的行只对锁定最初的线程是可行的,如果另外一个线程要向这些行中写数据,它就必须等到锁被释放。不过,其他
页中的行仍然是可以使用的。行级锁定: 与表级锁定或页级锁定相比,行级锁定提供了更精细的控制。在这种情况下,只有线程使用的行是被锁定
的,表中的其他行对于其他线程都是可用的。在多用户环境中,行级锁定降低了线程之间的冲突,可以使多个用户同时从同一个表中读取数据甚至写
数据。InnoDB表类型在事务中自动执行行级锁定。死锁 当多个用户同时访问一个数据库时,死锁是一种经常遇到的现象。如果两个用户都在
等待对方的数据,就会产生一个死锁。假如用户user1在R1行上定义了一个锁,并且希望在R2行上也放置一个锁,与此同时用户user2
是R2行上的一个锁的拥有者,并且希望在R1行上也放置一个锁,则这两个用户相互等待,从而产生死锁。在数据库应用开发中,要尽量降低发生
死锁的概率。7.2 锁定7.2.2 获取表级锁定使用LOCK TABLES语句显式获取当前客户端会话的表级锁定:LOCK TA
BLES表名 [[AS] 别名] 锁定类型[, 表名 [[AS] 别名] 锁定类型] ...锁定类型:{READ [LOCAL]
| [LOW_PRIORITY] WRITE}使用LOCK TABLES语句可以为基表或视图获取表级锁定。执行该语句时必须拥有对每
个要锁定对象的LOCK TABLES权限和SELECT权限。对于视图锁而言,LOCK TABLES语句将视图中使用的所有基表添加到
要锁定的表集当中并自动锁定它们。如果使用LOCK TABLES显式锁定表,则触发器中使用的任何表也将被隐式锁定。7.2 锁定7.
2.3 释放表级锁定使用UNLOCK TABLES语句显式释放当前会话持有的任何表级锁定:UNLOCK TABLESUNLOCK
TABLES语句还可以用于释放使用FLUSH TABLES WITH READ LOCK语句获取的全局读取锁定,这种形式的FLU
SH TABLES语句可以锁定所有数据库中的所有表。当释放会话持有的表级锁定时,它们将会同时释放。会话可以使用UNLOCK TAB
LES语句显式释放其锁定,也可以在某些条件下隐式释放锁定。如果在一个会话中发出LOCK TABLES语句,以便在已经持有锁定的情况
下获取锁定,则在授予新的锁定之前将会隐式释放其现有锁定。如果在会话中开始事务(例如使用START TRANSACTION语句),则
会隐式执行UNLOCK TABLES语句,这会导致释放现有锁定。7.2 锁定7.2.4 锁定与事务的交互LOCK TABLES
和UNLOCK TABLES与事务的相互作用表现在以下几个方面。(1)LOCK TABLES不是事务安全的,并且在尝试锁定表之前隐
式提交任何活动事务。(2)UNLOCK TABLES隐式提交任何活动事务,但仅当LOCK TABLES用于获取表级锁定时。例如,在
以下语句序列中,UNLOCK TABLES释放全局读锁但不会提交事务,因为没有表级锁定是有效的:(3)当开始事务(例如使用STAR
T TRANSACTION语句)时,将隐式提交任何当前事务并释放现有表级锁定。(4)具有READ LOCK的FLUSH TABLE
S获取全局读取锁定而不是表级锁定,因此在表级锁定和隐式提交方面,它不受与LOCK TABLES和UNLOCK TABLES相同的行
为约束。例如,START TRANSACTION不会释放全局读锁定。(5)隐式导致提交事务的其他语句不会释放现有的表级锁定。(6)
对事务表(如InnoDB表)使用LOCK TABLES和UNLOCK TABLES的正确方法是使用SET autocommit =
0禁用自动提交模式,而不是使用START TRANSACTION开始一个事务,然后使用LOCK TABLES,并且在明确提交事务
之前不要调用UNLOCK TABLES。(7)执行ROLLBACK语句不会释放表级锁定。7.2 锁定7.2.5 表级锁定与触发
器如果使用LOCK TABLES语句显式锁定表,则触发器中使用的任何表也会隐式锁定。(1)锁定与使用LOCK TABLES语句显式获取的锁定时间相同。(2)触发器中使用的表上的锁定取决于该表是否仅用于读取。如果是这样,则读取锁定就足够了,否则使用写入锁定。(3)如果为了读取数据而使用LOCK TABLES语句显式锁定表,又要为写入数据需要而锁定表(因为它可能在触发器中被修改),则将执行写入锁定而不是读取锁定。换言之,由于表在触发器中的出现而需要隐式写入锁定,这将导致表的显式读取锁定请求转换为写入锁定请求。7.2 锁定
献花(0)
+1
(本文系大高老师首藏)