事务控制语句,begin,rollback,savepoint,隐式提交的SQL语句
事务控制语句
在MySQL命令行的默认设置下,事务都是自动提交的,即执行SQL语句后就会马上执行COMMIT操作。因此开始一个事务,必须使用BEGIN、START TRANSACTION,或者执行SET AUTOCOMMIT=0,以禁用当前会话的自动提交。这和Microsoft SQL Server数据库的方式一致,需要显式地开始一个事务。而Oracle数据库不需要专门的语句来开始事务,事务会在修改数据的第一条语句处隐式地开始。
在具体介绍其含义之前,先来看看我们可以使用哪些事务控制语句:
- START TRANSACTION|BEGIN:显式地开启一个事务。
- COMMIT:要想使用这个语句的最简形式,只需发出COMMIT。也可以更详细一些,写为COMMIT WORK,不过这二者几乎是等价的。COMMIT会提交你的事务,并使得已对数据库做的所有修改成为永久性的。
- ROLLBACK:要想使用这个语句的最简形式,只需发出ROLLBACK。同样,你也可以写为ROLLBACK WORK,但是二者几乎是等价的。回滚会结束你的事务,并撤销正在进行的所有未提交的修改。
- SAVEPOINT identifier:SAVEPOINT允许你在事务中创建一个保存点,一个事务中可以有多个SAVEPOINT。
- RELEASE SAVEPOINT identifier:删除一个事务的保存点,当没有一个保存点执行这句语句时,会抛出一个异常。
- ROLLBACK TO[SAVEPOINT]identifier:这个语句与SAVEPOINT命令一起使用。可以把事务回滚到标记点,而不回滚在此标记点之前的任何工作。例如可以发出两条UPDATE语句,后面跟一个SAVEPOINT,然后又是两条DELETE语句。如果执行DELETE语句期间出现了某种异常情况,而且你捕获到这个异常,并发出ROLLBACK TO SAVEPOINT命令,事务就会回滚到指定的SAVEPOINT,撤销DELETE完成的所有工作,而UPDATE语句完成的工作不受影响。
- 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操作。
- 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。
- 用来隐式地修改mysql架构的操作:CREATE USER、DROP USER、GRANT、RENAME USER、REVOKE、SET PASSWORD。
- 管理语句: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语句的更多相关文章
- 显式提交/隐式提交 //ajax方式的隐式提交
//创建jqueryAjax.html文件 <!DOCTYPE html><html><head><meta charset="UTF-8" ...
- PB中获取datawindow提交的sql语句
PB的群里边,有人问的到这个问题,查了一下,综合了两条回答,得到了答案 1.DW 控件的SQLpreview 事件里的sqlsyntax 参数即是 2.pb一般使用占位符优化SQL语句,也就是你看到的 ...
- oracle中的隐式提交(auto commit)
通常我们执行sql或pl/sql时,需要我们手工提交.这样才能使所做的更改永久保存到数据库. 但有时即使我们没有在sql或pl/sql中发出commit命令,所做的更改也会被提交.这种提交是在某些特定 ...
- mysql跟踪提交的SQL语句
http://www.cnblogs.com/wuyifu/p/3328024.html
- 捕获长时间不提交的SQL语句
/* Formatted on 2014/5/19 17:16:16 (QP5 v5.240.12305.39476) */ SELECT s.sid, s.serial#, ss.sql_text ...
- sql语言分类及区别、显示和隐示提交的指令
SQL的发展是从1974年开始的,其发展过程如下: 1974年-----由Boyce和Chamberlin提出,当时称SEQUEL. 1976年-----IBM公司的Sanjase研究所在研制RDBM ...
- MYSQL中默认隐式事务及利用事务DML
一:默认情况下,MySQL采用autocommit模式运行.这意味着,当您执行一个用于更新(修改)表的语句之后,MySQL立刻把更新存储到磁盘中.默认级别为不可重复读. 二:会造成隐式提交的语句以下语 ...
- innodB的隐式锁
http://blog.csdn.net/taozhi20084525/article/details/19545231 一.知识准备之隐式锁 参考:http://www.uml.org.cn/sjj ...
- PL/SQL — 隐式游标
一.隐式游标的定义及其属性 定义 隐式游标由系统自动定义,非显示定义游标的DML语句即被赋予隐式游标属性.其过程由oracle控制,完全自动化.隐式游标的名称是SQL,不能对SQL游标显式地执行OPE ...
随机推荐
- 分析SQL Server Profiler的监控方式
记得某次给一家公司调优的时候,负责人发给我一堆业务的T-SQL脚本,我面对海量脚本还是从容,虽然不了解内部复杂的业务,但是我们得专注问题的关键 “慢”,我们根据查询的“慢”把他们筛选出来,一一调式优化 ...
- Bug报告提交规范
首先声明,bug的测试规范应该在公司的正式文档建立.本建议非正式文档,有些内容可能不正确,有些内容可能需要继续商榷,甚至有些内容同公司规范有冲突.如果发现问题,直接忽略本文相应内容.本帖本意仅就工作中 ...
- bootstrap-table简单使用
开发项目时总想着能不能有一款插件包含分页,查询等常用功能,后来发现了bootstrap-table 直接看代码和效果图 <!DOCTYPE html> <html lang=&quo ...
- 自己从0开始学习Unity的笔记 VIII (C#中类继承练习 II)
自己写了一个关于兵种的,因为一直在测试,到底面向对象是个什么玩意...然后就做了这个 namespace 兵种 { class Role //作为父类,构建一个普通角色属性用于继承 { protect ...
- 如何让Syncthing始终使用同一个设备ID?
设备ID(device id)是Syncthing最重要的参数之一,所有节点的发现.连接等操作,全部是基于这个设备ID!对于已经建立起来的P2P网络,保持重要节点的设备ID唯一性是非常重要的!!!!那 ...
- java springboot+maven发送邮件
springboot+maven发送邮件 废话不多说直接上代码 1. pom 文件导入jar包 <!--邮件发送--> <dependency> <groupId> ...
- Dubbo 自定义异常,你是怎么处理的?
前言 记录Dubbo对于自定义异常的处理方式. 实现目标 服务层异常,直接向上层抛出,web层统一捕获处理 如果是系统自定义异常,则返回{"code":xxx,"msg& ...
- 学习前端页面css定位
css元素框定位 一.相对定位: 相对定位是一个非常容易掌握的概念.如果对一个元素进行相对定位,它将出现在它所在的位置上.然后,可以通过设置垂直或水平位置,让这个元素“相对于”它的起点进行移动.pos ...
- Java NIO学习与记录(六): NIO线程模型
NIO线程模型 上一篇说的是基于操作系统的IO处理模型,那么这一篇来介绍下服务器端基于IO模型和自身线程的处理方式. 一.传统阻塞IO模型下的线程处理模式 这种处理模型是基于阻塞IO进行的,上一篇讲过 ...
- python全栈开发_day13_迭代器和生成器
一:迭代器 1)可迭代对象 具有内置函数__iter__的数据就是可迭代对象 2)迭代器对象 具有内置函数__next__的数据就是迭代器对象 迭代器对象一定是可迭代对象,可迭代对象不一定是迭代器对象 ...