MySQL详解(14)----------事务处理

前言:前一篇文章关于事务处理的博文没有写清楚,读起来很晦涩,很难理解,所以有整理了一些资料,帮助理解,见谅!

关于MySQL事务处理学习记

START TRANSACTION

COMMIT

ROLLBACK

语法

START TRANSACTION    |

BEGIN [WORK]

COMMIT   [WORK]    [AND [NO] CHAIN]    [  [NO] RELEASE  ]

ROLLBACK  [WORK]  [AND  [NO]  CHAIN]   [  [NO] RELEASE  ]

SET AUTOCOMMIT = {0 | 1}

START TRANSACTION或BEGIN语句可以开始一项新的事务。

COMMIT可以提交当前事务,是变更成为永久变更。

ROLLBACK可以 回滚当前事务,取消其变更。

SET AUTOCOMMIT语句可以禁用或启用默认的autocommit模式,用于当前连接。

自选的WORK关键词被支持,用于COMMIT和RELEASE,与CHAIN和RELEASE子句。

CHAIN和RELEASE可以被用于对事务完成进行附加控制。

Completion_type系统变量的值决定了默认完成的性质。

AND CHAIN子句会在当前事务结束时,立刻启动一个新事务,并且新事务与刚结束的事务有相同的隔离等级。

RELEASE子句在终止了当前事务后,会让服务器断开与当前客户端的连接。包含NO关键词可以抑制CHAIN或RELEASE完成。

如果completion_type系统变量被设置为一定的值,使连锁或释放完成可以默认进行,此时NO关键词有用。

默认情况下,MySQL采用autocommit模式运行。这意味着,当您执行一个用于更新(修改)表的语句之后,MySQL立刻把更新存储到磁盘中。

如果您正在使用一个事务安全型的存储引擎(如InnoDB, BDB或NDB簇),则您可以使用以下语句禁用autocommit模式:

SET AUTOCOMMIT=0; 通过把AUTOCOMMIT变量设置为零,禁用autocommit模式之后,您必须使用COMMIT把变更存储到磁盘中,或着如果您想要忽略从事务开始进行以来做出的变更,使用ROLLBACK。

如果您想要对于一个单一系列的语句禁用autocommit模式,则您可以使用START TRANSACTION语句:

START TRANSACTION;

SELECT @A:=SUM(salary) FROM table1 WHERE type=1;

UPDATE table2 SET [email protected] WHERE type=1; COMMIT;

使用START TRANSACTION,autocommit仍然被禁用,直到您使用COMMIT或ROLLBACK结束事务为止。

然后autocommit模式恢复到原来的状态。

BEGIN和BEGIN WORK被作为START TRANSACTION的别名受到支持,用于对事务进行初始化。

START TRANSACTION是标准的SQL语法,并且是启动一个ad-hoc事务的推荐方法。

BEGIN语句与BEGIN关键词的使用不同。BEGIN关键词可以启动一个BEGIN...END复合语句。后者不会开始一项事务。

您也可以按照如下方法开始一项事务:

START TRANSACTION WITH CONSISTENT SNAPSHOT;

WITH CONSISTENT SNAPSHOT子句用于启动一个一致的读取,用于具有此类功能的存储引擎。

目前,该子句只适用于InnoDB。该子句的效果与发布一个START TRANSACTION,后面跟一个来自任何InnoDB表的SELECT的效果一样。

开始一项事务会造成一个隐含的UNLOCK TABLES被执行。

为了获得最好的结果,事务应只使用由单一事务存储引擎管理的表执行。否则,会出现以下问题:

如果您使用的表来自多个事务安全型存储引擎(例如InnoDB和BDB),并且事务隔离等级不是SERIALIZABLE,则有可能当一个事务提交时,其它正在进行中的、使用同样的表的事务将只会发生由第一个事务产生的变更。

也就是,用混合引擎不能保证事务的原子性,并会造成不一致。(如果混合引擎事务不经常有,则您可以根据需要使用

SET TRANSACTION ISOLATION LEVEL把隔离等级设置到SERIALIZABLE。)

如果您在事务中使用非事务安全型表,则对这些表的任何变更被立刻存储,不论autocommit模式的状态如何。

如果您在更新了事务中一个事务表之后,发布一个ROLLBACK语句,则会出现一个ER_WARNING_NOT_COMPLETE_ROLLBACK警告。

对事务安全型表的变更被 回滚,但是对非事务安全型表没有变更。

每个事务被存储在一个组块中的二进制日志中,在COMMIT之上。被回滚的事务不被计入日志。(例外情况:对非事务表的更改不会被 回滚。如果一个被回滚的事务包括对非事务表的更改,则整个事务使用一个在末端的ROLLBACK语句计入日志,以确保对这些表的更改进行复制。)

您可以使用SET TRANSACTION ISOLATION LEVEL更改事务的隔离等级。

回滚可以慢速运行。在用户没有明确要求时,也可以进行回滚(例如,当错误发生时)。因此,在明确地和隐含的(ROLLBACK SQL命令)回滚时,SHOW PROCESSLIST会在Stage列中显示Rolling back,用于连接。

    事务处理和并发性

1.1.        基础知识和相关概念

1 )全部的表类型都可以使用锁,但是只有 InnoDB 和 BDB 才有内置的事务功能。

2 )使用 begin 开始事务,使用 commit 结束事务,中间可以使用 rollback 回滚事务。

3 )在默认情况下, InnoDB 表支持一致读。

SQL 标准中定义了 4 个隔离级别: read uncommited , read commited , repeatable read , serializable 。

read uncommited 即脏读,一个事务修改了一行,另一个事务也可以读到该行。

如果第一个事务执行了回滚,那么第二个事务读取的就是从来没有正式出现过的值。 ?

read commited 即一致读,试图通过只读取提交的值的方式来解决脏读的问题,但是这又引起了不可重复读取的问题。

一个事务执行一个查询,读取了大量的数据行。在它结束读取之前,另一个事务可能完成了对数据行的更改。当第一个事务试图再次执行同一个查询,服务器就会返回不同的结果。

repeatable read 即可重复读,在一个事务对数据行执行读取或写入操作时锁定了这些数据行。

但是这种方式又引发了幻想读的问题。

因为只能锁定读取或写入的行,不能阻止另一个事务插入数据,后期执行同样的查询会产生更多的结果。

serializable 模式中,事务被强制为依次执行。这是 SQL 标准建议的默认行为。

4 )如果多个事务更新了同一行,就可以通过回滚其中一个事务来解除死锁。

5 ) MySQL 允许利用 set transaction 来设置隔离级别。

6 )事务只用于 insert 和 update 语句来更新数据表,不能用于对表结构的更改。执行一条更改表结构或 begin 则会立即提交当前的事务。

7 )所有表类型都支持表级锁,但是 MyISAM 只支持表级锁。

8 )有两种类型的表级锁:读锁和写锁。

读锁是共享锁,支持并发读,写操作被锁。

写锁是独占锁,上锁期间其他线程不能读表或写表。

8 )如果要支持并发读写,建议采用 InnoDB 表,因为它是采用行级锁,可以获得更多的更新性能。

9 )很多时候,可以通过经验来评估什么样的锁对应用程序更合适,不过通常很难说一个锁比别的更好,这全都要依据应用程序来决定,不同的地方可能需要不同的锁。当前 MySQL 已经支持 ISAM, MyISAM, MEMORY (HEAP) 类型表的表级锁了, BDB 表支持页级锁, InnoDB 表支持行级锁。

10 ) MySQL 的表级锁都是写锁优先,而且是采用排队机制,这样不会出现死锁的情况。对于 InnoDB 和 BDB 存储引擎来说,是可能产生死锁的。这是因为 InnoDB 会自动捕获行锁, BDB 会在执行 SQL 语句时捕获页锁的,而不是在事务的开始就这么做。

1.2.        不同锁的优缺点及选择

行级锁的优点及选择 :

1 )在很多线程请求不同记录时减少冲突锁。

2 )事务回滚时减少改变数据。

3 )使长时间对单独的一行记录加锁成为可能。

行级锁的缺点 :

1 )比页级锁和表级锁消耗更多的内存。

2 )当在大量表中使用时,比页级锁和表级锁更慢,因为他需要请求更多的所资源。

3 )当需要频繁对大部分数据做 GROUP BY 操作或者需要频繁扫描整个表时,就明显的比其它锁更糟糕。

4 )使用更高层的锁的话,就能更方便的支持各种不同的类型应用程序,因为这种锁的开销比行级锁小多了。

5 )可以用应用程序级锁来代替行级锁,例如 MySQL 中的 GET_LOCK() 和 RELEASE_LOCK() 。但它们是劝告锁(原文: These are advisory locks ),因此只能用于安全可信的应用程序中。

6 )对于 InnoDB 和 BDB 表, MySQL 只有在指定用 LOCK TABLES 锁表时才使用表级锁。在这两种表中,建议最好不要使用 LOCK TABLES ,因为 InnoDB 自动采用行级锁, BDB 用页级锁来保证事务的隔离。

表锁的优点及选择:

1 )很多操作都是读表。

2 )在严格条件的索引上读取和更新,当更新或者删除可以用单独的索引来读取得到时: UPDATE tbl_name SET column=value WHERE unique_key_col=key_value;DELETE FROM tbl_name WHERE unique_key_col=key_value;

3 ) SELECT 和 INSERT 语句并发的执行,但是只有很少的 UPDATE 和 DELETE 语句。

4 )很多的扫描表和对全表的 GROUP BY 操作,但是没有任何写表。

表锁的缺点:

1 )一个客户端提交了一个需要长时间运行的 SELECT 操作。

2 )其他客户端对同一个表提交了 UPDATE 操作,这个客户端就要等到 SELECT 完成了才能开始执行。

3 )其他客户端也对同一个表提交了 SELECT 请求。由于 UPDATE 的优先级高于 SELECT ,所以 SELECT 就会先等到 UPDATE 完成了之后才开始执行,它也在等待第一个 SELECT 操作。

1.3.        如何避免锁的资源竞争

1 )让 SELECT 速度尽量快,这可能需要创建一些摘要表。

2 )启动 mysqld 时使用参数 --low-priority-updates 。这就会让更新操作的优先级低于 SELECT 。

这种情况下,在上面的假设中,第二个 SELECT 就会在 INSERT 之前执行了,而且也无需等待第一个 SELECT 了。

3 )可以执行 SET LOW_PRIORITY_UPDATES=1 命令,指定所有的更新操作都放到一个指定的链接中去完成。

4 )用 LOW_PRIORITY 属性来降低 INSERT , UPDATE , DELETE 的优先级。

5 )用 HIGH_PRIORITY 来提高 SELECT 语句的优先级。

6 )从 MySQL 3.23.7 开始,可以在启动 mysqld 时指定系统变量 max_write_lock_count 为一个比较低的值,它能强制临时地提高表的插入数达到一个特定值后的所有 SELECT 操作的优先级。它允许在 WRITE 锁达到一定数量后有 READ 锁。

7 )当 INSERT 和 SELECT 一起使用出现问题时,可以转而采用 MyISAM 表,它支持并发的 SELECT 和 INSERT 操作。

8 )当在同一个表上同时有插入和删除操作时, INSERT DELAYED 可能会很有用。

9 )当 SELECT 和 DELETE 一起使用出现问题时, DELETE 的 LIMIT 参数可能会很有用。

10 )执行 SELECT 时使用 SQL_BUFFER_RESULT 有助于减短锁表的持续时间。

11 )可以修改源代码 `mysys/thr_lock.c‘ ,只用一个所队列。这种情况下,写锁和读锁的优先级就一样了,这对一些应用可能有帮助。

版权声明:欢迎转转载,希望转载的同时添加原文地址,谢谢合作,学习快乐!

时间: 2024-10-15 02:19:05

MySQL详解(14)----------事务处理的相关文章

Linux下彻底卸载mysql详解

Linux下彻底卸载mysql详解 一.使用以下命令查看当前安装mysql情况,查找以前是否装有mysql 1 rpm -qa|grep -i mysql 可以看到如下图的所示: 显示之前安装了: MySQL-client-5.5.25a-1.rhel5 MySQL-server-5.5.25a-1.rhel5 2.停止mysql服务.删除之前安装的mysql 删除命令:rpm -e –nodeps 包名 1 2 rpm -ev MySQL-client-5.5.25a-1.rhel5  rpm

linux上源码安装MySQL详解

最近需要使用MySQL Fabric,这货是MySQL5.6.10之后才出现的utility.手头机器装的是MySQL5.1,所以需要先把旧版MySQL升级成5.6版本.之前没有玩过MySQL,所以这次稍微费了点事.在此,把过程记录下来,希望能给有需求的人提供一点帮助.下面我们就正式开始. 1. 删除老版本MySQL 其实删除老版MySQL是一件很简单的事,但是开始时候由于担心各个包的依赖会导致各种问题,亦步亦趋来得很慢.其实只需要做到这么几步就可以了: 1.1 查看已安装的mysql版本并删除

Ubuntu 16.04下安装MySQL详解

Ubuntu 16.04下安装MySQL详解分别依次输入以下3个命令: sudo apt-get install mysql-server sudo apt install mysql-client sudo apt install libmysqlclient-dev 安装成功后可以通过下面的命令测试是否安装成功: sudo netstat -tap | grep mysql 出现如下信息证明安装成功: >>> sudo netstat -tap | grep mysql tcp 0

mysql详解安装

三种安装方式 1 二进制  解压就用 2 YUM/RPM   适用于很多台服务器安装,编译好后,做成RPM包 适用于yum仓库 3 编译安装     自定安装,相当于自己DIY了...5.1安装用make,5.5安装要用cmake 安装二进制详解演示!! 显示系统名.节点名称.操作系统的发行版号.操作系统版本.运行系统的机器 ID 号. [[email protected] ~]# uname -aLinux sky-mysql 2.6.32-573.el6.x86_64 #1 SMP Thu

MySql 详解

MySql数据库基础 MySQL各大存储引擎 MySql常用字符集 MySql支持的数据类型 MySql 枚举和集合 详解 MySql 约束条件 MySql 表操作 MySql 多表关系 MySql 范式 MySql 单表查询 MySql 多表查询 MySQL权限详解 Mysql 三大特性详解 原文地址:https://www.cnblogs.com/TMesh-python/p/11731303.html

图像处理中的数学原理详解14——曲面积分

欢迎关注我的博客专栏"图像处理中的数学原理详解" 全文目录请见 图像处理中的数学原理详解(总纲) http://blog.csdn.net/baimafujinji/article/details/48467225 图像处理中的数学原理详解(已发布的部分链接整理) http://blog.csdn.net/baimafujinji/article/details/48751037 我整理了图像处理中可能用到的一些数学基础,将其分成了6个章节(全文目录见上方链接).如果你对其中的某一小节

MySQL详解--锁

来源:http://blog.csdn.net/xifeijian/article/details/20313977#t4 锁是计算机协调多个进程或线程并发访问某一资源的机制.在数据库中,除传统的计算资源(如CPU.RAM.I/O等)的争用以外,数据也是一种供许多用户共享的资源.如何保证数据并发访问的一致性.有效性是所有数据库必须解决的一个问题,锁冲突也是影响数据库并发访问性能的一个重要因素.从这个角度来说,锁对数据库而言显得尤其重要,也更加复杂.本章我们着重讨论MySQL锁机制的特点,常见的锁

转摘: MySQL详解--锁

原文 http://blog.csdn.net/xifeijian/article/details/20313977 InnoDB锁问题 InnoDB与MyISAM的最大不同有两点:一是支持事务(TRANSACTION):二是采用了行级锁.行级锁与表级锁本来就有许多不同之处,另外,事务的引入也带来了一些新问题.下面我们先介绍一点背景知识,然后详细讨论InnoDB的锁问题. 背景知识 1.事务(Transaction)及其ACID属性 事务是由一组SQL语句组成的逻辑处理单元,事务具有以下4个属性

Ubuntu安装配置Mysql详解

Ubuntu安装配置Mysql 三种安装方式: 1. 从网上安装 sudo apt-get install mysql-server.装完已经自动配置好环境变量,可以直接使用mysql的命令. 注:建议将/etc/apt/source.list中的cn改成us,美国的服务器比中国的快很多. 2. 安装离线包,以mysql-5.0.45-linux-i686-icc-glibc23.tar.gz为例. 3. 二进制包安装:安装完成已经自动配置好环境变量,可以直接使用mysql命令 网上安装和二进制