事务控制语句

在MySQL命令行的默认设置下,事务都是自动提交的,即执行SQL语句后就会马上执行COMMIT操作。因此开始一个事务,必须使用BEGIN、START TRANSACTION,或者执行SET AUTOCOMMIT=0,以禁用当前会话的自动提交。这和Microsoft SQL Server数据库的方式一致,需要显式地开始一个事务。而Oracle数据库不需要专门的语句来开始事务,事务会在修改数据的第一条语句处隐式地开始。

在具体介绍其含义之前,先来看看我们可以使用哪些事务控制语句:

  1. START TRANSACTION|BEGIN:显式地开启一个事务。
  2. COMMIT:要想使用这个语句的最简形式,只需发出COMMIT。也可以更详细一些,写为COMMIT WORK,不过这二者几乎是等价的。COMMIT会提交你的事务,并使得已对数据库做的所有修改成为永久性的。
  3. ROLLBACK:要想使用这个语句的最简形式,只需发出ROLLBACK。同样,你也可以写为ROLLBACK WORK,但是二者几乎是等价的。回滚会结束你的事务,并撤销正在进行的所有未提交的修改。
  4. SAVEPOINT identifier:SAVEPOINT允许你在事务中创建一个保存点,一个事务中可以有多个SAVEPOINT。
  5. RELEASE SAVEPOINT identifier:删除一个事务的保存点,当没有一个保存点执行这句语句时,会抛出一个异常。
  6. ROLLBACK TO[SAVEPOINT]identifier:这个语句与SAVEPOINT命令一起使用。可以把事务回滚到标记点,而不回滚在此标记点之前的任何工作。例如可以发出两条UPDATE语句,后面跟一个SAVEPOINT,然后又是两条DELETE语句。如果执行DELETE语句期间出现了某种异常情况,而且你捕获到这个异常,并发出ROLLBACK TO SAVEPOINT命令,事务就会回滚到指定的SAVEPOINT,撤销DELETE完成的所有工作,而UPDATE语句完成的工作不受影响。
  7. SET TRANSACTION:这个语句用来设置事务的隔离级别。InnoDB存储引擎提供的事务隔离级别有:READ UNCOMMITTED、READ COMMITTED、REPEATABLE READ、SERIALIZABLE。

START TRANSACTION、BEGIN语句都可以在mysql命令行下显式地开启一个事务。但是在存储过程中,MySQL分析会自动将BEGIN识别为BEGIN……END。因此在存储过程中,只能使用START TRANSACTION语句来开启一个事务。

COMMIT和COMMIT WORK语句基本是上一致的,都是用来提交事务。不同之处在于,COMMIT WORK用来控制事务结束后的行为,是CHAIN还是RELEASE的。可以通过参数completion_type来进行控制,默认情况下该参数为0,表示没有任何操作。在这种设置下,COMMIT和COMMIT WORK是完全等价的。

当参数completion_type的值为1时,COMMIT WORK等同于COMMIT AND CHAIN,表示马上自动开启一个相同隔离级别的事务,如:

create table t(a int,primary key(a))engine=innodb;

select @@autocommit\G

@@autocommit:1

set @@completion_type=1;

begin;

insert into t select 1;

commit work;

insert into t select 2;

insert into t select 2;

ERROR 1062(23000):Duplicate entry '2' for key'PRIMARY'

rollback;

#注意回滚之后只有1这个记录,而没有2这个记录

select * from t\G

我们将completion_type设置为1,第一次通过COMMIT WORK来插入1这个记录。之后插入记录2时我们并没有用BEGIN(或者START TRANSACTION)来开启一个事务,之后再插入一条重复的记录2,这时会抛出异常。我们执行ROLLBACK操作,最后发现只有1这一个记录,2并没有被插入。因为completion_type为1时,COMMIT WORK会自动开启一个事务,因此两个INSERT语句是在同一个事务内的,因此回滚后就没有进行插入。

参数completion_type为2时,COMMIT WORK等同于COMMIT AND RELEASE。当事务提交后会自动断开与服务器的连接,如:

set @@completion_type=2;

begin;

insert into t select 3;

commit work;

select @@version\G

ERROR 2006(HY000):MySQL server has gone away

No connection.Trying to reconnect……

Connection id:54

Current database:test

***************************1.row***************************

@@version:5.1.45-log

1 row in set(0.00 sec)

通过上面的实验可以发现,当参数completion_type设置为2时,COMMIT WORK后,我们再执行select @@version,会出现ERROR 2006(HY000):MySQL server has gone away的错误,这其实就是因为当前会话已经在上次执行COMMIT WORK语句后与服务器断开了连接。

ROLLBACK和ROLLBACK WORK与COMMIT和COMMIT WORK的工作一样,不再赘述。

SAVEPOINT记录了一个保存点,可以通过ROLLBACK TO SAVEPOINT回滚到某个保存点,但是如果回滚到一个不存在的保存点,会抛出异常:

begin;

rollback to savepoint t1;

ERROR 1305(42000):SAVEPOINT t1 does not exist

InnoDB存储引擎中的事务都是原子的,这说明下述两种情况:或者构成事务的每条语句都会提交(成为永久),或者所有语句都回滚。这种保护还延伸到单个的语句。一条语句要么完全成功,要么完全回滚(注意,我说的是语句回滚)。如果一条语句失败,并不会导致先前已经执行的语句自动回滚。它们的工作会保留,必须由你来决定是否对其进行提交或回滚操作。如:

create table t(a int,primary key(a))engine=innodb;

begin;

insert into t select 1;

insert into t select 1;

ERROR 1062(23000):Duplicate entry'1'for key'PRIMARY'

select * from t\G

可以看到,插入第二记录1时,因为重复的关系抛出了1062的错误,但是数据库并没有进行自动回滚,这时事务仍需要我们显式地运行COMMIT或者ROLLBACK。

另一个容易犯的错误是ROLLBACK TO SAVEPOINT,虽然有ROLLBACK,但是它并不是真正地结束一个事务,因此即使执行了ROLLBACK TO SAVEPOINT,之后也需要显式地运行COMMIT或者ROLLBACK命令。

create table t(a int,primary key(a))engine=innodb;

begin;

insert into t select 1;

savepoint t1;

insert into t select 2;

savepoint t2;

release savepoint t1;

insert into t select 2;

ERROR 1062(23000):Duplicate entry'2'for key'PRIMARY'

rollback to savepoint t2;

select * from t;

rollback;

select * from t;

Empty set(0.00 sec)

在上面的例子中可以看到,虽然我们在发生重复错误后,通过ROLLBACK TO SAVEPOINT t2命令回滚到了保存点t2,但是事务此时并没有结束,我们再接着运行ROLLBACK后,事务才完整回滚。需要再次提醒的是,ROLLBACK TO SAVEPOINT命令并不真正地结束事务。

隐式提交的SQL语句

以下这些SQL语句会产生一个隐式的提交操作,即执行完这些语句后,会有一个隐式的COMMIT操作。

  1. DDL语句:ALTER DATABASE……UPGRADE DATA DIRECTORY NAME、ALTER EVENT、ALTER PROCEDURE、ALTER TABLE、ALTER VIEW、CREATE DATABASE、CREATE EVENT、CREATE INDEX、CREATE PROCEDURE、CREATE TABLE、CREATE TRIGGER、CREATE VIEW、DROP DATABASE、DROP EVENT、DROP INDEX、DROP PROCEDURE、DROP TABLE、DROP TRIGGER、DROP VIEW、RENAME TABLE、TRUNCATE TABLE。
  2. 用来隐式地修改mysql架构的操作:CREATE USER、DROP USER、GRANT、RENAME USER、REVOKE、SET PASSWORD。
  3. 管理语句:ANALYZE TABLE、CACHE INDEX、CHECK TABLE、LOAD INDEX INTO CACHE、OPTIMIZE TABLE、REPAIR TABLE。

注意:我发现Microsoft SQL Server的数据库管理员或者开发人员往往忽视对于DDL语句的隐式提交操作,因为在Microsoft SQL Server数据库中,即使是DDL也是可以回滚的。这和InnoDB存储引擎、Oracle数据库都不同。

TRUNCATE TABLE语句是DDL,因此虽然和DELETE整张表的结果是一样的,但它是不能被回滚的(这又是和Microsoft SQL Server数据不同的地方):

select * from t\G

begin;

truncate table t;

rollback;

select * from t;

Empty set(0.00 sec)

事务控制语句,begin,rollback,savepoint,隐式提交的SQL语句的更多相关文章

  1. 显式提交/隐式提交 //ajax方式的隐式提交

    //创建jqueryAjax.html文件 <!DOCTYPE html><html><head><meta charset="UTF-8" ...

  2. PB中获取datawindow提交的sql语句

    PB的群里边,有人问的到这个问题,查了一下,综合了两条回答,得到了答案 1.DW 控件的SQLpreview 事件里的sqlsyntax 参数即是 2.pb一般使用占位符优化SQL语句,也就是你看到的 ...

  3. oracle中的隐式提交(auto commit)

    通常我们执行sql或pl/sql时,需要我们手工提交.这样才能使所做的更改永久保存到数据库. 但有时即使我们没有在sql或pl/sql中发出commit命令,所做的更改也会被提交.这种提交是在某些特定 ...

  4. mysql跟踪提交的SQL语句

    http://www.cnblogs.com/wuyifu/p/3328024.html

  5. 捕获长时间不提交的SQL语句

    /* Formatted on 2014/5/19 17:16:16 (QP5 v5.240.12305.39476) */ SELECT s.sid, s.serial#, ss.sql_text ...

  6. sql语言分类及区别、显示和隐示提交的指令

    SQL的发展是从1974年开始的,其发展过程如下: 1974年-----由Boyce和Chamberlin提出,当时称SEQUEL. 1976年-----IBM公司的Sanjase研究所在研制RDBM ...

  7. MYSQL中默认隐式事务及利用事务DML

    一:默认情况下,MySQL采用autocommit模式运行.这意味着,当您执行一个用于更新(修改)表的语句之后,MySQL立刻把更新存储到磁盘中.默认级别为不可重复读. 二:会造成隐式提交的语句以下语 ...

  8. innodB的隐式锁

    http://blog.csdn.net/taozhi20084525/article/details/19545231 一.知识准备之隐式锁 参考:http://www.uml.org.cn/sjj ...

  9. PL/SQL — 隐式游标

    一.隐式游标的定义及其属性 定义 隐式游标由系统自动定义,非显示定义游标的DML语句即被赋予隐式游标属性.其过程由oracle控制,完全自动化.隐式游标的名称是SQL,不能对SQL游标显式地执行OPE ...

随机推荐

  1. 咏南LINUX中间件

    咏南LINUX中间件 什么是跨平台? DELPHI跨平台已经不是停留在理论,而是可以实用了. 同一套中间件既能在WINDOWS服务器上面部署,又可以在LINUX服务器上面部署. 而做到这一切,只需要一 ...

  2. AndroidStudio-Error Loading Project: Cannot load 3 facets

    Error Loading Project: Cannot load 3 facets 解决方法,在 File-->Settings-->Plugins-----> 勾选 Andro ...

  3. csv文件乱码

    问题描述: 生成的csv文件,设置为UTF-8格式,在windows上用EXCEL打开的话会乱码,在linux上用vim或者cat打开查看正常:设置为GBK格式的话,在windows上用EXCEL打开 ...

  4. Application可以被重用,从哪里看出来的?

    一开始Context是静态的,并且创建时赋值,然后校验用户访问权限的时候,出现了问题, 调试看到,每次请求的url都一样,我就发现了每次Contetx都是一样的, 说明每次请求的Application ...

  5. pageadmin CMS网站建设教程:网页设计的常用参数

    由于网络速度问题,我们需要考虑图片大小对传输速度的影响,如果图片太大就会影响浏览速度,访问者很快就会对这个网站失去了兴趣,只有充分了解图片质量与下载速度的关系,并了解不同的文件格式,才能更有效的表达内 ...

  6. C语言--第0次作业;

    第零次作业 1.你对网络专业或者计算机专业了解是怎样? 在高考之前,我就确定了自己的大学专业将会选择计算机方面.我认为计算机专业就业前景比较好,计算机行业发展也非常快,学科实践与创新能力也比较强,在当 ...

  7. BZOJ 1922--大陆争霸(最短路)

    1922: [Sdoi2010]大陆争霸 Time Limit: 10 Sec  Memory Limit: 64 MBSubmit: 2113  Solved: 947[Submit][Status ...

  8. 【awk】按小时切割日志

    需求: 把日志按日志内容中的小时数做切割 {hostname=ali-beijing-msync-3512} 2017-05-17 23:17:52.694 [info] <0.27292.70 ...

  9. day 09 课后作业

    # -*- coding: utf-8 -*-# @Time : 2018/12/28 14:25# @Author : Endless-cloud# @Site : # @File : 08 课后作 ...

  10. python要点记录

    1.字典:当存储的key数目在几万到几十万之间效率最高.