事务控制语句

在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. [Erlang31]Erlang trace总结

    在一个并行的世界里面,我们很难做到单步断点调试来定位问题(太多的消息飞来飞去),Erlang设计者也深刻体会到这一点,推出了另一个trace机制. 通过这个trace,你可以: .特定进程集内的函数调 ...

  2. 遇到了IE10不能登录的问题,很早就有解决方案了

    1..net 2.0 的程序,请打开项目,打开vs开发环境的工具菜单下的  Package Manager Console ,中文名:程序包管理控制台,在打开的控制台中输入如下命令:Install-P ...

  3. java的一些命名规范吧

    注意事项: 1.由于Java是面向对象编程的,所以在命名的时候尽量选择名词. 2.(Camel-Case)驼峰命名法:当变量名或函式名是由一个或多个单字连结在一起,而构成的唯一识别字时,首字母以小写开 ...

  4. C# superGridControl 样式设置、加载数据、获取数据

    样式设置 superGridControl1.PrimaryGrid.SelectionGranularity = SelectionGranularity.Cell; //设置选中样式 单元格.整列 ...

  5. js 倒计时,转义

    function leftTimer(time) { var leftTime = (new Date(time)) - (new Date()); //计算剩余的毫秒数 var days = par ...

  6. [.net]ConcurrentBag源码分析

    ConcurrentBag根据操作线程,对不同线程分配不同的队列进行数据操作.这样,每个队列只有一个线程在操作,不会发生并发问题.其内部实现运用了net4.0新加入的ThreadLocal线程本地存储 ...

  7. WP8.1StoreApp(WP8.1RT)---SystemTray的变化

    原Microsoft.Phone.Shell中的SystemTray,已经改到Windows.UI.ViewManagement中StatusBar了. 只能在代码中设置相关属性. 如: 1 2 3 ...

  8. [uwp]自定义Behavior之随意拖动

    由于最近有需求,所以自定义了一个随意拖动元素的Behavior. 当然在使用这个自定义的Behavior时,有个小假设:拖动元素必须是Canvas容器的子元素. 实现原理比较简单低效: 监听被拖动元素 ...

  9. php中mvc框架总结1(7)

    1.代码结构的划分: 目前的目录结构: /站点根目录 /application/应用程序目录 Model/模型目录 View/视图目录 Back/后台 front/ test/测试平台 Control ...

  10. [agc006f] Blackout 神题

    Description ​ 给你一个NN行NN列的网格,第ii行第jj列的格子用(i,j)(i,j)表示 一开始的时候有MM个格子被涂成黑色,其他的格子都是白色,具体一点,涂成黑色的格子为(a1,b1 ...