MySQL中事务的分类
MySQL中事务的分类
从事务理论的角度来看,可以把事务分为以下几种类型
扁平事务(Flat Transactions)
带有保存点的扁平事务(Flat Transactions with Savepoints)
链事务(Chained Transactions)
嵌套事务(Nested Transactions)
分布式事务(Distributed Transactions)
扁平事务 是事务类型中最简单的一种,但是在实际生产环境中,这可能是使用最频繁的事务,在扁平事务中,所有操作都处于同一层次,其由BEGIN WORK开始,由COMMIT WORK或ROLLBACK WORK结束,其间的操作是源自的,要么都执行,要么都回滚,因此扁平事务是应用程序称为原子操作的的基本组成模块
下面显示了扁平事务的三种不同结果
给出的扁平事务的三种情况,同时也给出了一个典型的事务处理应用中,每个结果大概占用的百分比。再次提醒,扁平事务虽然简单,但是在实际环境中使用最为频繁,也正因为其简单,使用频繁,故每个数据库系统都实现了对扁平事务的支持
扁平事务的主要限制是不能提交或者回滚事务的某一部分,或分几个步骤提交。下面给出一个扁平事务不足以支持的例子。例如用户在旅行网站上进行自己的旅行度假计划,用户设想从杭州到意大利的佛罗伦萨,这两个城市没有直达的班机,需要用户预订并转呈航班,需要或者搭火车等待。用户预订旅行度假的事务为
BEGIN WORK:
S1:预订杭州到上海的高铁
S2:上海浦东国际机场坐飞机,预订到米兰的航班
S3:在米兰转火车前往佛罗伦萨,预订去佛罗伦萨的火车
但是当用户执行到S3时,发现由于飞机到达米兰的时间太晚,已经没有当天的火车,这时用户希望在米兰当地住一晚,第二天出发去佛罗伦萨。这时如果事务为扁平事务,需要回滚之前S1 S2 S3的三个操作,这个代价明显很大,因为当再次进行该事务是,S1 S2的执行计划是不变的,也就是说,如果支持有计划的回滚操作,那么不需要终止整个事务,因此就出现了带有保存点的扁平事务
带有保存点的扁平事务 除了支持扁平事务支持的操作外,允许在事务执行过程中回滚同一事务中较早的一个状态。这是因为某些事务可能在执行过程中出现的错误并不会导致所有的操作都无效,放弃整个事务不合乎要求,开销太大,保存点用来通知事务系统应该记住事务当前的状态,以便当之后发生错误时,事务能回到保存点当时的状态
对于扁平的事务来说,隐式的设置了一个保存点。然而整个事务中,只有这一个保存点,因此,回滚只能会滚到事务开始时的状态,保存点用SAVE WORK函数来建立,通知系统记录当前的处理状态。当出现问题时,保存点能用作内部的重启动点,根据应用逻辑,决定是回到最近一个保存点还是其他更早的保存点。图显示了事务中使用的保存点
显示了如何在事务中使用保存点,灰色背景部分表示由ROLLBACK WORK而导致部分回滚,实际并没有执行操作,当用BEGIN WORK开启一个事务时,隐式地包含了一个保存点,当事务通过ROLLBACK WORK:2发出部分回滚命令时,事务会滚到保存点2,接着依次执行,并再次执行到ROLLBACK WORK:7,知道最后COMMIT WORK操作,表示事务结束,除灰色阴影部分的操作外,其余操作都已经执行,并且提交
另一个需要注意的是,保存点在事务内部是递增的,从图中可以看出,有人可能会想,返回保存点2以后,下一个保存点可以为3,因为之前的工作已经终止,然而新的保存点编号为5,这意味着ROLLBACKU 不影响保存点的计数,并且单调递增编号能保持事务执行的整个历史过程,包括在执行过程中想法的改变
此外,当事务通过ROLLBACK WORK:2命令发出部分回滚命令时,要记住事务并没有完全被回滚,只是回滚到保存点2而已,这代表当前事务是活跃的,如果想要回滚事务,还需要执行ROLLBACKUP WORK
链事务 可视为保存点模式的一种变种,带有保存点的扁平事务,当发生系统崩溃是,所有的的保存点都将消失,因为其保存点是易失的,这意味着当进行恢复时,事务需要从开始处重新执行,而不能从最近的一个保存点继续执行
链事务的思想是:在提交一个事务时,释放不需要的数据对象,将必要的处理上下文隐式地传给下一个要开始的事务,提交事务操作和开始下一个事务操作 将合并为一个原子操作,这意味着下一个事务将看到上一个事务的结果,就好像一个事务中进行的一样,如图显示了链事务的工作方式
链事务与带有保存点的扁平事务不同的是,带有保存点的扁平事务能回滚到任意正确的保存点,而链事务中的回滚仅限当前事务,即只能恢复到最近的一个保存点,对于锁的处理,两者也不相同,锁事务在执行COMMIT后即释放了当前所持有的锁,而带有保存点的扁平事务不影响迄今为止所持有的锁
嵌套事务 是一个层次结构框架,由一个顶层事务(top-level transaction)控制着各个层次的事务,顶层事务之下嵌套的事务被称为子事务,其控制每一个局部的变换,结构如下
下面给出MOSS对嵌套事务的定义
1 嵌套事务是由若干事务组成的一棵树,子树既可以是嵌套事务也可以是扁平事务
2 处在叶节点的事务是扁平事务,但是每个事务从根到叶节点的距离可以说是不同的
3 位于根节点的事务称为顶层事务,其他称为自事务。事务的前驱称(predecessor)为父事务(parent),事务的下一层称为儿子事务(child)
4 子事务既可以提交也可以回滚。但是它的提交操作并不马上生效。除非其父事务已经提交。因此可以推论出,任何子事务都在顶层事务提交后才真正的提交
5 树中的任意事务回滚会引起它的所有子事务一同回滚,故子事务仅保留ACI特性而不具有D特性
在Moss的理论中,实际的工作是交由叶子节点完成,即只有叶子节点的事务才能才能访问数据库、发送信息、获取其他类型的资源。而高层的事务仅负责逻辑控制。决定合适调用相关的子事务。即使一个系统不支持嵌套事务,用户也可以通过保存点技术来模拟嵌套事务,如图
如图可以发现,在恢复时采用保存点技术比嵌套查询有更大的灵活性。例如在完成Tk3这事务时,可以会滚到保存点S2的状态。而在嵌套查询的层次结构中,这是不被允许的
但是用保存点技术来模拟嵌套事务在锁的持有方面还是与嵌套查询有些区别。当通过保存点技术来模拟嵌套事务时,用户无法选择哪些锁需要被子事务集成,哪些需要被父事务保留,这就是说,无论有多少个保存点,所有被锁住的队形都可以被得到和访问。而在嵌套查询中,不同的子事务在数据库对象上持有的锁是不同观点。例如一个父事务P1 其持有对象X和Y的排他锁,现在要开始调用子事务P11 ,那么父事务P1 可以不传递锁,也可以传递所有的锁,也可以只传递一个排他锁,如果子事务P11 中还持有对象Z的排他锁,那么通过反向继承(counter-inherited)父事务P1 将持有3个对象X Y Z的排他锁。如果这时再次调用一个子事务P12 ,那么它可以传递哪里已经持有的锁
然而,如果系统支持嵌套事务中并行地执行的各个子事务,在这种情况下,采用保存点的扁平事务来模拟嵌套事务就不切实际了。这从另一个方面反映出,想要实现事务间的并行性,需要真正支持的嵌套事务
分布式事务 通常是一个分布式环境下运行的扁平事务,因此需要根据数据所在位置访问网络中的不同节点
假如一个用户在ATM机上进行银行的转账操作,例如持卡人从招商银行存储卡转账10 000 元到工商银行的存储卡。这种情况下,可以将ATM机视为节点A,招商银行的后台数据库视为节点B,工商银行的后台数据库视为C,这个转账的操作可分解为以下的步骤
节点A发出转账命令
节点B执行存储卡中的余额减去10 000
节点C执行存储卡终端的余额增加10 000
节点A通知用户操作完成或者节点A通知用户操作失败
这里需要使用到分布式事务,因为节点A不能通过一台数据库就完成任务,其需要访问网络中两个节点的数据库,而在每个节点的数据库执行的实务操作有都是扁平的,对于分布式事务,其同样需要满足ACID特性,要么都发生,要么都失败。对于上述例子,如果2 3 步中任何一个操作失败,都会导致整个分布式事务回滚,若非这样,结果非常可怕
对于InnoDB存储引擎来说,其支持扁平事务,带保存点的事务,链事务,分布式事务。对于嵌套事务,其原生不支持。因此对有并发事务需求的用户来说,MySQL数据库或InnoDB存储引擎就显得无能为力,然而用户仍可以通过带保存点的事务来模拟串行的嵌套事务
事务(Transaction)是数据库区别于文件系统的重要特性之一,事务会把数据库从一种一致性状态转换为另一种一致性状态。在数据库提交时,可以确保要么所有修改都已保存,要么所有修改都不保存。
事务的ACID特性
事务必须同时满足ACID的特性:
- 原子性(Atomicity)。事务中的所有操作要么全部执行成功,要么全部取消。
- 一致性(Consistency)。事务开始之前和结束之后,数据库完整性约束没有破坏。
- 隔离性(Isolation)。事务提交之前对其它事务不可见。
- 持久性(Durability)。事务一旦提交,其结果是永久的。
事务的分类
从事务理论的角度可以把事务分为以下几种类型:
- 扁平事务(Flat Transactions)
- 带有保存节点的扁平事务(Flat Transactions with Savepoints)
- 链事务(Chained Transactions)
- 嵌套事务(Nested Transactions)
- 分布式事务(Distributed Transactions)
扁平事务
扁平事务(Flat Transactions)是事务类型中最简单但使用最频繁的事务。在扁平事务中,所有的操作都处于同一层次,由BEGIN/START TRANSACTION开始事务,由COMMIT/ROLLBACK结束,且都是原子的,要么都执行,要么都回滚。因此扁平事务是应用程序成为原子操作的基本组成模块。扁平事务一般有三种不同的结果:
1.事务成功完成。在平常应用中约占所有事务的96%。
2.应用程序要求停止事务。比如应用程序在捕获到异常时会回滚事务,约占事务的3%。
3.外界因素强制终止事务。如连接超时或连接断开,约占所有事务的1%。
扁平事务的主要限制是不能提交或者回滚事务的某一部分。如果某一事务中有多个操作,在一个操作有异常时并不希望之的操作全部回滚,而是保存前面操作的更改。扁平事务并不能支持这样的事例,因此就出现了带有保存节点的扁平事务。
带有保存节点的扁平事务
带有保存节点的扁平事务(Flat Transactions with Savepoints)允许事务在执行过程中回滚到较早的一个状态,而不是回滚所有的操作。保存点(Savepoint)用来通知系统应该记住事务当前的状态,以便当之后发生错误时,事务能回到保存点当时的状态。
对于扁平事务来说,在事务开始时隐式地设置了一个保存点,回滚时只能回滚到事务开始时的状态。下图是回滚到某个保存节点的实例:
链事务
链事务(Chained Transaction)是指一个事务由多个子事务链式组成。前一个子事务的提交操作和下一个子事务的开始操作合并成一个原子操作,这意味着下一个事务将看到上一个事务的结果,就好像在一个事务中进行的一样。这样,在提交子事务时就可以释放不需要的数据对象,而不必等到整个事务完成后才释放。其工作方式如下:
链事务与带保存节点的扁平事务不同的是,链事务中的回滚仅限于当前事务,相当于只能恢复到最近的一个保存节点,而带保存节点的扁平事务能回滚到任意正确的保存点。但是,带有保存节点的扁平事务中的保存点是易失的,当发生系统崩溃是,所有的保存点都将消失,这意味着当进行恢复时,事务需要从开始处重新执行。
嵌套事务
嵌套事务(Nested Transaction)是一个层次结构框架。由一个顶层事务(top-level transaction)控制着各个层次的事务。顶层事务之下嵌套的事务成为子事务(subtransaction),其控制着每一个局部的操作,子事务本身也可以是嵌套事务。因此,嵌套事务的层次结构可以看成是一颗树,其结构如下图所示。
分布式事务
分布式事务(Distributed Transactions)通常是一个在分布式环境下运行的扁平事务,因此需要根据数据所在位置访问网络中不同节点的数据库资源。
例如一个银行用户从招商银行的账户向工商银行的账户转账1000元,这里需要用到分布式事务,因为不能仅调用某一家银行的数据库就完成任务。
事务的隔离级别
SQL标准定义的四个隔离级别:
- READ UNCOMMITTED
- READ COMMITTED
- REPEATABLE READ
- SERIALIZABLE
这些隔离级别定义了事务中哪些数据的改变对其它事务可见,哪些数据的改变对其它事务不可见,事务的隔离级别可以使用以下语句进行设置。
READ UNCOMMITTED
读取未提交内容。在该隔离级别下,所有事务都可以看到其它未提交事务的执行结果。如下图所示:
事务2查询到的数据是事务1中修改但未提交的数据,但因为事务1回滚了数据,所以事务2查询的数据是不正确的,因此出现了脏读的问题。
READ COMMITTED
读取提交内容。在该隔离级别下,一个事务从开始到提交之前对数据所做的改变对其它事务是不可见的,这样就解决在READ-UNCOMMITTED级别下的脏读问题。但如果一个事务在执行过程中,其它事务的提交对该事物中的数据发生改变,那么该事务中的一个查询语句在两次执行过程中会返回不一样的结果。如下图所示:
事务2执行update语句但未提交前,事务1的前两个select操作返回结果是相同的。但事务2执行commit操作后,事务1的第三个select操作就读取到事务2对数据的改变,导致与前两次select操作返回不同的数据,因此出现了不可重复读的问题。
REPEATABLE READ
可重复读。这是MySQL的默认事务隔离级别,能确保事务在并发读取数据时会看到同样的数据行,解决了READ-COMMITTED隔离级别下的不可重复读问题。MySQL的InnoDB存储引擎通过多版本并发控制(Multi_Version Concurrency Control, MVCC)机制来解决该问题。在该机制下,事务每开启一个实例,都会分配一个版本号给它,如果读取的数据行正在被其它事务执行DELETE或UPDATE操作(即该行上有排他锁),这时该事物的读取操作不会等待行上的锁释放,而是根据版本号去读取行的快照数据(记录在undo log中),这样,事务中的查询操作返回的都是同一版本下的数据,解决了不可重复读问题。其原理如下图所示:
虽然该隔离级别下解决了不可重复读问题,但理论上会导致另一个问题:幻读(Phantom Read)。正如上面所讲,一个事务在执行过程中,另一个事物对已有数据行的更改,MVCC机制可保障该事物读取到的原有数据行的内容相同,但并不能阻止另一个事务插入新的数据行,这就会导致该事物中凭空多出数据行,像出现了幻读一样,这便是幻读问题。如下图所示:
事务2对id=1的行内容进行了修改并且执行了commit操作,事务1中的第二个select操作在MVCC机制的作用下返回的仍是v=1的数据。但事务3执行了insert操作,事务1第三次执行select操作时便返回了id=2的数据行,与前两次的select操作返回的值不一样。
需要说明的是,REPEATABLE-READ隔离级别下的幻读问题是SQL标准定义下理论上会导致的问题,MySQL的InnoDB存储引擎在该隔离级别下,采用了Next-Key Locking锁机制避免了幻读问题。Next-Key Locking锁机制将在后面的锁章节中讲到。
SERIALIZABLE
可串行化。这是事务的最高隔离级别,通过强制事务排序,使之不可能相互冲突,就是在每个读的数据行加上共享锁来实现。在该隔离级别下,可以解决前面出现的脏读、不可重复读和幻读问题,但也会导致大量的超时和锁竞争现象,一般不推荐使用。
MySQL事务概述
为了防止无良网站的爬虫抓取文章,特此标识,转载请注明文章出处。LaplaceDemon/SJQ。
http://www.cnblogs.com/shijiaqi1066/p/3858050.html
1 事务(Transaction)概述
1.1 数据库事务的四个特性:ACID
原子性(Atomicity)
整个事务中的所有操作,要么全部完成,要么全部不完成。
一致性(Consistency)
数据库一致性(Database Consistency)是指事务执行的结果必须是使数据库从一个一致性状态变到另一个一致性状态。
隔离性(Isolation)
又称为孤立性。多个人执行多个事务,事务需要隔离。即事务不能同时进行。
持久性(Durability)
保证即便断电,也能正常工作。
1.2 事务的分类
扁平事务
最典型的事务,由BEGIN WORK开始,由COMMIT WORK或ROLLBACK WORK结束,其间的操作都是原子的。要么执行,要么回滚。
带有保存点的事务
在基于扁平事务的基础上,允许在事务执行过程中回滚到事务中较早的一个状态。
链事务
保存点事务的一种变种。保存点事务在系统崩溃时,所有的保存点都是易失的,即系统恢复时,事务需要从开始出重新执行,而不能从最近的保存点继续执行。
链事务指的是在提交事务时,释放不需要的数据对象,将必要的处理上下文隐式地传给下一个要开始的事务。提交事务和开始下一个事务将合并为一个原子操作。即下一个事务将看到上一个事务的结果,就好象在一个事务中进行一样。
链事务与带有保存点的事务不同,带有保存点的事务能回滚到任意正确的保存点。而链事务中的回滚仅限于当前保存点。
嵌套事务
嵌套事务是一个层次结构框架。有一个顶层事务控制各个层次的事务。顶层事务之下嵌套的事务被称为子事务。
父事务回滚,子事务也会被回滚。即子事务具备,ACI的特性,不具备D的特性。
分布式事务
分布式事务是在分布式环境下运行的扁平事务。
对于InnoDB存储引擎,支持扁平事务,带有保存点的事务、链事务、分布式事务。但不支持嵌套事务。
1.3 事务的隔离级别
ANSI/ISO SQL标准(SQL92)定义了四种事务隔离级别(transaction isolation level)。这些事务隔离级别是针对三种现象定义的,在并发事务执行时,需要阻止这三种现象中的一种或多种发生。
三种需要阻止的现象(preventable phenomena)是:
脏读取(dirty read):简称“脏读”。指一个事务读取了被其他事务写入但还未提交的数据。
不可重复读取(nonrepeatable read):一个事务再次读取其之前曾经读取过的数据时,发现数据已被其他已提交的事务修改或删除。
不存在读取(phantom read):简称“幻读”。事务按照之前的条件重新查询时,返回的结果集中包含其他已提交事务插入的满足条件的新数据。
辨析:不可重复读与幻读的区别
不可重复读与幻读,这种现象有些类似。
不可重复读的重点是修改:同样的条件, 读取过的数据, 再次读取出来发现值不一样。若需要避免该现象,只需要锁住满足条件的记录。
幻读的重点在于新增或者删除:同样的条件, 第1次和第2次读出来的记录数不一样。若需要避免该现象,要锁住满足条件及其相近的记录,或直接锁表。
SQL标准定义了4类隔离级别如下:
Read Uncommitted(未提交读)
所有事务都可以看到其他未提交事务的执行结果,即允许脏读。该隔离级别,很少实际应用。
Read Committed(已提交读)
一个事务只能看见已经提交事务所做的改变。即不允许脏读。但允许不可重复读,因为其他事务在当前事务的处理其间可能会有新的commit,所以前后的select可能返回不同结果。
Repeatable Read(可重复读)
确保一个事务在重复读取数据时,对重复读取到的数据行的值是不变的。避免了不可重复读。但无法避免幻读。即一个事务重复读取数据时,可能会发现有新的“幻影”行。
Serializable(可串行化)
串行的对事务进行处理。强制事务排序,使之不可能相互冲突,从而解决幻读问题。
只有当事务提交后,其他事务才能从数据库中查看数据的变化。
这是最高的隔离级别,在这个级别,可能导致大量的超时现象和锁竞争。
不同级别的隔离方法可以避免一定的现象:
\ 现象 隔离级别 \ | 脏读取 | 不可重复读取 | 幻读 |
未提交读 | 允许 | 允许 | 允许 |
已提交读 | 不允许 | 允许 | 允许 |
可重复读 | 不允许 | 不允许 | 允许 |
可串行化 | 不允许 | 不允许 | 不允许 |
2 MySQL的事务
2.1 MySQL的事务处理命令
在命令行交互环境下,或存储过程中,可以使用如下命令方便的操作事务。
初始化事务
命令:START TRANSACTION;
事务回滚
命令:ROLLBACK;
提交事务
命令:COMMIT;
设置保存点
命令:SAVEPOINT identifer
删除事务的保存点
命令:RELEASE SAVEPOINT identifer
回滚至保存点
命令:ROLLBACK TO [SAVEPOINT] identifer
自动提交
在MySQL中,若不更改其自动提交变量,则系统会自动向数据库提交结果。
关闭自动提交:SET AUTOCOMMIT = 0;
关闭自动提交之后,只有使用COMMIT命令后,才会提交事务。
查看AUTOCOMMIT值:
命令:select @@autocommit;
或命令:show variables like 'autocommit';
2.2 事务的实现
事务的隔离性由数据库的锁来实现。原子性,一致性,持久性由数据库的redo log和undo log来完成。
- redo log称为重做日志,用于保证事务的原子性和持久性。
- undo log用来保证事务的一致性。
2.3 MySQL的隔离级别
MySQL的默认事务隔离级别为Repeatable Read(可重复读)
MySQL中InnoDB存储引擎结合了MVCC和Next-Key Lock锁的算法,避免了幻读的产生。InnoDB存储引擎在默认的Repeatable Read的事务隔离级别下,已经非常接近Serializable隔离级别。(避免幻读,并不代表就完全等于了Serializable隔离级别。)
查看当前数据库使用的隔离级别。global.tx_isolation变量表示全局事务。tx_isolation表示当前会话的事务。
命令:select @@global.tx_isolation , @@tx_isolation;
修改当前数据库使用的隔离级别,使用SET语句对tx_isolation变量进行设置。用户需要有SUPER权限,才可以执行进行隔离级别的修改。
基本命令格式:SET [GLOBAL | SESSION] TRANSACTION ISOLATION LEVEL { READ UNCOMMITTED | READ COMMITTED | REPEATABLE READ | SERIALIZABLE }
在默认情况下,SET TRANSACTION会为下一个事务(还未开始)设置隔离等级。
若使用GLOBAL关键词,则语句会设置全局性的默认事务等级,用于从该点以后创建的所有新连接。原有的连接不受影响。
若使用SESSION可以设置默认事务等级,用于对当前连接的事务。
例:将当前会话的事务隔离级别设置为Read Uncommitted(未提交读)。
命令:SET SESSION TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;
2.4 分布式事务
InnoDB存储引擎支持XA事务,通过XA事务实现分布式事务。使用分布式事务时,InnoDB存储引擎的隔离级别必须设置为SERIALIZABLE。
XA事务允许不同数据库的分布式事务,只要参与在全局事务中的每个节点都支持XA事务。Oracle,SQL Server都支持XA事务。
XA事务由一个或多个资源管理器、一个事务管理器以及一个应用程序组成。
- 资源管理器:提供访问事务资源的方法。通常一个数据库就是一个资源管理器。
- 事务管理器:协调参与全局事务中的各个事务。需要和参与全局事务的所有资源管理器进行通信。
- 应用程序:定义事务的边界。
2.5 事务与性能
很多应用其实是不需要事务的。例,在数据仓库中,若没有ETL这些操作,只是简单的报表查询是不需要事务的。
传统观点认为,事务隔离级别越高,数据越安全,但性能就越慢。事务隔离级别越低,性能就越快,但数据越不安全。
但在Jim Gray在《Transaction Processing》一书中指出,REPEATABLE READ 与SERIALIZABLE 的开销几乎是一样的。SERIALIZABLE 甚至可能更优。READ UNCOMMITTED的隔离级别也不会有太大的性能提升。
2.6 锁的简要介绍与使用
数据库锁也就是所谓的悲观锁。
2.6.1 锁的类型
读锁
又称共享锁、S锁。被锁定对象只允许被读,不允许被写。
若事务T对数据对象A加上读锁,则事务T可以读A但不能修改A,其他事务只能再对A加读锁,而不能加写锁,直到事务T释放A上的读锁。
写锁
又称排他锁、X锁。
若事务T对数据对象A加上写锁,事务T可以读A也可以修改A,其他事务不能读A,也不能再对A加任何锁,直到T释放A上的锁。
2.6.2 表级锁
操作对象是数据表,是系统开销最低但并发性最低的一个锁策略。
命令格式:LOCK TABLES 表1 锁类型, 表2 锁类型 ... ;
LOCK命令可以同时对多张表加锁。锁类型为READ、WRITE。
例:对student表添加读锁。
命令:lock tables student read;
例:对student表添加写锁。
命令:lock tables student write;
在用LOCK TABLES给表显式加表锁时,必须同时取得所有涉及到表的锁,并且MySQL不支持锁升级。也就是说,在执行LOCK TABLES后,只能访问显式加锁的这些表,不能访问未加锁的表;同时,如果加的是读锁,那么只能执行查询操作,而不能执行更新操作。其实,在自动加锁的情况下也基本如此,MyISAM总是一次获得SQL语句所需要的全部锁。这也正是MyISAM表不会出现死锁(Deadlock Free)的原因。
解锁
命令:UNLOCK TABLES;
UNLOCK命令会释放所有处于锁定状态的数据表。
2.6.3 行级锁
操作对象是数据表中的一行。行级锁对系统开销较大,处理高并发较好。
行级别的读锁
命令格式:SELECT ... LOCK IN SHARE MODE;
MySQL会对查询结果集中每行都添加共享锁。
行级别的写锁
命令格式:SELECT ... FOR UPDATE;
MySQL会对查询结果集中每行都添加排他锁,在事物操作中,任何对记录的更新与删除操作会自动加上排他锁。
2.6.4 死锁
多个资源的并发经常会发生死锁现象。
表级锁是不会产生死锁的。MyISAM使用表级锁模拟事务是安全的。
InnoDB引擎拥有自动检查死锁的功能。当发现死锁现象,会自动解决死锁问题。
2.6.5 MySQL伪事务
由于MyISAM存储引擎可以支持表锁(不支持行级锁)。可以使用表级锁模拟事务。这种模拟的事务侧重点在于操作的隔离。这不是真正的事务,不具备回滚的操作。
表级锁是不会产生死锁,可以安全使用。
2.7 MVCC
MVCC,Multiversion Currency Control,即多版本并发控制。
一般情况下,事务性储存引擎不是只使用表锁,行加锁的处理数据,而是结合了MVCC机制,以处理更多的并发问题。MVCC处理高并发能力最强,但系统开销比最大(相对于表锁、行级锁),这是最求高并发付出的代价。
在MySQL中MVCC是在Innodb存储引擎中得到支持的,Innodb为每行记录都实现了三个隐藏字段:
6字节的事务ID(DB_TRX_ID )
7字节的回滚指针(DB_ROLL_PTR)
隐藏的ID
使用这三个字段,利用类似于乐观锁的机制实现了近似的MVCC机制。具体原理参看相关参考资料。
关于MVCC的一些参考资料:
http://coolshell.cn/articles/6790.html
http://www.jayxu.com/2012/03/13/13326/
http://jishu.zol.com.cn/2960.html
http://blog.csdn.net/chen77716/article/details/6742128
About Me
.............................................................................................................................................
● 本文整理自网络
● 本文在itpub(http://blog.itpub.net/26736162/abstract/1/)、博客园(http://www.cnblogs.com/lhrbest)和个人微信公众号(xiaomaimiaolhr)上有同步更新
● 本文itpub地址:http://blog.itpub.net/26736162/abstract/1/
● 本文博客园地址:http://www.cnblogs.com/lhrbest
● 本文pdf版、个人简介及小麦苗云盘地址:http://blog.itpub.net/26736162/viewspace-1624453/
● 数据库笔试面试题库及解答:http://blog.itpub.net/26736162/viewspace-2134706/
● DBA宝典今日头条号地址:http://www.toutiao.com/c/user/6401772890/#mid=1564638659405826
.............................................................................................................................................
● QQ群号:230161599(满)、618766405
● 微信群:可加我微信,我拉大家进群,非诚勿扰
● 联系我请加QQ好友(646634621),注明添加缘由
● 于 2017-08-01 09:00 ~ 2017-08-31 22:00 在魔都完成
● 文章内容来源于小麦苗的学习笔记,部分整理自网络,若有侵权或不当之处还请谅解
● 版权所有,欢迎分享本文,转载请保留出处
.............................................................................................................................................
● 小麦苗的微店:https://weidian.com/s/793741433?wfr=c&ifr=shopdetail
● 小麦苗出版的数据库类丛书:http://blog.itpub.net/26736162/viewspace-2142121/
.............................................................................................................................................
使用微信客户端扫描下面的二维码来关注小麦苗的微信公众号(xiaomaimiaolhr)及QQ群(DBA宝典),学习最实用的数据库技术。
小麦苗的微信公众号 小麦苗的DBA宝典QQ群1 小麦苗的DBA宝典QQ群2 小麦苗的微店
.............................................................................................................................................
来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/26736162/viewspace-2144050/,如需转载,请注明出处,否则将追究法律责任。
©著作权归作者所有:来自51CTO博客作者小麦苗DB宝的原创作品,如需转载,请注明出处,否则将追究法律责任更多相关文章
- 事务的4种隔离级别(Isolation Level)分别是什么?
- spring事务详解(三)源码详解
- pexpect-2.3安装方法
- MVCC(Multi-Version Concurrent Control,多版本并发控制)简介
- 事务的4个特性——ACID(原子性、一致性、隔离性和持久性)、更新丢
- 【MySQL】MySQL的四种事务隔离级别
- ORACLE 回滚段详解
- MySQL InnoDB之锁机制
- mysql sync_binlog和 innodb_flush_log_at_trx_commit