从SQL语言的分类谈COMMIT和ROLLBACK的用法
来源:互联网 发布:手机二次元壁纸软件 编辑:程序博客网 时间:2024/05/21 15:47
从SQL语言的分类谈COMMIT和ROLLBACK的用法
mysql的autocommit(自动提交)默认是开启,其对mysql的性能有一定影响,举个例子来说,如果你插入了1000条数据,mysql会commit1000次的,如果我们把autocommit关闭掉,通过程序来控制,只要一次commit就可以了。
1,我们可以通过set来设置autocommit
- mysql> set global init_connect="set autocommit=0"; //提示你用权限更高的财户来设置
- ERROR 1227 (42000): Access denied; you need (at least one of) the SUPER privilege(s) for this operation
- mysql> set autocommit=0;
- Query OK, 0 rows affected (0.00 sec)
-
- mysql> select @@autocommit; //查看一下autocommit的设置
- +--------------+
- | @@autocommit |
- +--------------+
- | 0 |
- +--------------+
- 1 row in set (0.00 sec)
2,我们可以修改mysql的配置文件my.cnf来关闭autocommit
- [mysqld]
- init_connect='SET autocommit=0' //在mysqld里面加上这些内容
用第二种方法关,有一点要注意,连接mysql用户的权限不能大于启动mysql的用户的权限,不然init_connect='SET autocommit=0'根本不会启作用,也不会报任何错误,汗一个先。看以下实例
- zhangy@ubuntu:~$ mysql -umysql
- Welcome to the MySQL monitor. Commands end with ; or \g.
- Your MySQL connection id is 1
- Server version: 5.5.2-m2-log Source distribution
-
- Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
-
- mysql> select @@autocommit; //mysql是启动用户,关闭autocommit成功
- +--------------+
- | @@autocommit |
- +--------------+
- | 0 |
- +--------------+
- 1 row in set (0.00 sec)
-
- mysql> Ctrl-C -- exit!
- Aborted
- zhangy@ubuntu:~$ mysql -uroot
- Welcome to the MySQL monitor. Commands end with ; or \g.
- Your MySQL connection id is 2
- Server version: 5.5.2-m2-log Source distribution
-
- Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
-
- mysql> select @@autocommit; //用root财户启动,不成功。
- +--------------+
- | @@autocommit |
- +--------------+
- | 1 |
- +--------------+
- 1 row in set (0.00 sec)
这个会不会是mysql的bug呢?我在网上找了找这方面的问题,还真有。部分内容如下:
If a user has SUPER privilege, init_connect will not execute
(otherwise if init_connect will a wrong query no one can connect to server).
Note, if init_connect is a wrong query, the connection is closing without any errors
and next command will clause 'lost connection' error.
里面有一点说的很清楚If a user has SUPER privilege, init_connect will not execute,如果用户有更高级的权限,init_connect根本不会执行。
2013-08-08 16:55:21
mysql的autocommit(自动提交)默认是开启,其对mysql的性能有一定影响,举个例子来说,如果你插入了1000条数据,mysql会commit1000次的,如果我们把autocommit关闭掉,通过程序来控制,只要一次commit就可以了。
1,我们可以通过set来设置autocommit
- mysql> set global init_connect="set autocommit=0"; //提示你用权限更高的财户来设置
- ERROR 1227 (42000): Access denied; you need (at least one of) the SUPER privilege(s) for this operation
- mysql> set autocommit=0;
- Query OK, 0 rows affected (0.00 sec)
- mysql> select @@autocommit; //查看一下autocommit的设置
- +--------------+
- | @@autocommit |
- +--------------+
- | 0 |
- +--------------+
- 1 row in set (0.00 sec)
2,我们可以修改mysql的配置文件my.cnf来关闭autocommit
- [mysqld]
- init_connect='SET autocommit=0' //在mysqld里面加上这些内容
用第二种方法关,有一点要注意,连接mysql用户的权限不能大于启动mysql的用户的权限,不然init_connect='SET autocommit=0'根本不会启作用,也不会报任何错误,汗一个先。看以下实例
- zhangy@ubuntu:~$ mysql -umysql
- Welcome to the MySQL monitor. Commands end with ; or \g.
- Your MySQL connection id is 1
- Server version: 5.5.2-m2-log Source distribution
- Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
- mysql> select @@autocommit; //mysql是启动用户,关闭autocommit成功
- +--------------+
- | @@autocommit |
- +--------------+
- | 0 |
- +--------------+
- 1 row in set (0.00 sec)
- mysql> Ctrl-C -- exit!
- Aborted
- zhangy@ubuntu:~$ mysql -uroot
- Welcome to the MySQL monitor. Commands end with ; or \g.
- Your MySQL connection id is 2
- Server version: 5.5.2-m2-log Source distribution
- Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
- mysql> select @@autocommit; //用root财户启动,不成功。
- +--------------+
- | @@autocommit |
- +--------------+
- | 1 |
- +--------------+
- 1 row in set (0.00 sec)
这个会不会是mysql的bug呢?我在网上找了找这方面的问题,还真有。部分内容如下:
If a user has SUPER privilege, init_connect will not execute
(otherwise if init_connect will a wrong query no one can connect to server).
Note, if init_connect is a wrong query, the connection is closing without any errors
and next command will clause 'lost connection' error.
里面有一点说的很清楚If a user has SUPER privilege, init_connect will not execute,如果用户有更高级的权限,init_connect根本不会执行。
mysql的autocommit(自动提交)默认是开启,其对mysql的性能有一定影响,举个例子来说,如果你插入了1000条数据,mysql会commit1000次的,如果我们把autocommit关闭掉,通过程序来控制,只要一次commit就可以了。
1,我们可以通过set来设置autocommit
- mysql> set global init_connect="set autocommit=0"; //提示你用权限更高的财户来设置
- ERROR 1227 (42000): Access denied; you need (at least one of) the SUPER privilege(s) for this operation
- mysql> set autocommit=0;
- Query OK, 0 rows affected (0.00 sec)
- mysql> select @@autocommit; //查看一下autocommit的设置
- +--------------+
- | @@autocommit |
- +--------------+
- | 0 |
- +--------------+
- 1 row in set (0.00 sec)
2,我们可以修改mysql的配置文件my.cnf来关闭autocommit
- [mysqld]
- init_connect='SET autocommit=0' //在mysqld里面加上这些内容
用第二种方法关,有一点要注意,连接mysql用户的权限不能大于启动mysql的用户的权限,不然init_connect='SET autocommit=0'根本不会启作用,也不会报任何错误,汗一个先。看以下实例
- zhangy@ubuntu:~$ mysql -umysql
- Welcome to the MySQL monitor. Commands end with ; or \g.
- Your MySQL connection id is 1
- Server version: 5.5.2-m2-log Source distribution
- Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
- mysql> select @@autocommit; //mysql是启动用户,关闭autocommit成功
- +--------------+
- | @@autocommit |
- +--------------+
- | 0 |
- +--------------+
- 1 row in set (0.00 sec)
- mysql> Ctrl-C -- exit!
- Aborted
- zhangy@ubuntu:~$ mysql -uroot
- Welcome to the MySQL monitor. Commands end with ; or \g.
- Your MySQL connection id is 2
- Server version: 5.5.2-m2-log Source distribution
- Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
- mysql> select @@autocommit; //用root财户启动,不成功。
- +--------------+
- | @@autocommit |
- +--------------+
- | 1 |
- +--------------+
- 1 row in set (0.00 sec)
这个会不会是mysql的bug呢?我在网上找了找这方面的问题,还真有。部分内容如下:
If a user has SUPER privilege, init_connect will not execute
(otherwise if init_connect will a wrong query no one can connect to server).
Note, if init_connect is a wrong query, the connection is closing without any errors
and next command will clause 'lost connection' error.
里面有一点说的很清楚If a user has SUPER privilege, init_connect will not execute,如果用户有更高级的权限,init_connect根本不会执行。
事务定义:
事务是单个的工作单元。如果某一事务成功,则在该事务中进行的所有数据更改均会
提交,成为数据库中的永久组成部分。如果事务遇到错误且必须取消或回滚,则所有
数据更改均被清除。
事务三种运行模式:
自动提交事务
每条单独的语句都是一个事务。
显式事务
每个事务均以 BEGIN TRANSACTION 语句显式开始,
以 COMMIT 或 ROLLBACK 语句显式结束。
隐性事务
在前一个事务完成时新事务隐式启动,但每个事务仍以 COMMIT 或 ROLLBACK 语句
显式完成。
事务操作的语法:
BEGIN TRANSACTION
BEGIN DISTRIBUTED TRANSACTION
COMMIT TRANSACTION
COMMIT WORK
ROLLBACK WORK
SAVE TRANSACTION
BEGIN TRANSACTION
BEGIN TRANSACTION
标记一个显式本地事务的起始点。
BEGIN TRANSACTION将 @@TRANCOUNT 加 1。
BEGIN TRANSACTION 代表一点,由连接引用的数据在该点是逻辑和物理上都一致的。如果遇上错误,在 BEGIN TRANSACTION 之后的所有数据改动都能进行回滚,以将数据返回到已知的一致状态 。每个事务继续执行直到它无误地完成并且用 COMMIT TRANSACTION 对数据库作永久的改动,或者遇上错误并且用 ROLLBACK TRANSACTION 语句擦除所有改动
语法
BEGIN TRAN [ SACTION ] [ transaction_name | @tran_name_variable [ WITH MARK [ 'description' ] ] ]
例子:
BEGIN TRAN T1
UPDATE table1 ...
--nest transaction M2
BEGIN TRAN M2 WITH MARK
UPDATE table2 ...
SELECT * from table1
COMMIT TRAN M2
UPDATE table3 ...
COMMIT TRAN T1
BEGIN DISTRIBUTED TRANSACTION
指定一个由 Microsoft 分布式事务处理协调器 (MS DTC) 管理的 Transact-SQL 分布式事务的起始。
语法
BEGIN DISTRIBUTED TRAN [ SACTION ]
[ transaction_name | @tran_name_variable ]
参数
transaction_name
是用户定义的事务名,用于跟踪 MS DTC 实用工具中的分布式事务。 transaction_name 必须符合标识符规则,但是仅使用头 32 个字符
@tran_name_variable
是用户定义的一个变量名,它含有一个事务名,该事务名用于跟踪 MS DTC 实用工具中的分布式事务。必须用 char、varchar、nchar 或nvarchar 数据类型声明该变量。
注释
执行BEGIN DISTRIBUTED TRANSACTION 语句的服务器是事务创建人,并且控制事务的完成
当连接发出后续 COMMIT TRANSACTION 或 ROLLBACK TRANSACTION 语句时,
主控服务器请求 MS DTC 在所涉及的服务器间管理分布式事务的完成。
有两个方法可将远程 SQL 服务器登记在一个分布式事务中:
分布式事务中已登记的连接执行一个远程存储过程调用,该调用引用一个远程服务器。
分布式事务中已登记的连接执行一个分布式查询,该查询引用一个远程服务器。
示例
本例在本地和远程数据库上更新作者的姓。本地和远程数据库将同时提交或同时回滚本事务。
说明
当前的SQL Server 上必须安装 MS DTC.
USE pubs
GO
BEGIN DISTRIBUTED TRANSACTION
UPDATE authors
SET au_lname = 'McDonald' WHERE au_id = '409-56-7008'
EXECUTE link_Server_T.pubs.dbo.changeauth_lname '409-56-7008','McDonald'
COMMIT TRAN
GONote:
如果需要连接远程DB,如果是linkServer 方式连接的话,一定要修该linkServer的 RPC 选项置为 True。
SET XACT_ABORT
指定当 Transact-SQL 语句产生运行时错误时,Microsoft? SQL Server? 是否自动回滚当前事务。
( 可以比较简单的理解,如果中间有任何一句SQL 出错,所有SQL全部回滚.特别适用于 Procedure 中间调用Procedure ,如果第一个Procedure Ok,被调用的Procedure 中间有错误,如果SET XACT_ABORT=false,则出错的部分回滚,其他部分提交,当然外部Procedure 也提交。).
---在分布式Trans中一定要注意设置下面参数(XACT_ABORT)
语法SET XACT_ABORT { ON | OFF }
注释 当 SET XACT_ABORT 为 ON 时,如果 Transact-SQL 语句产生运行时错误,整个事务将终止并回滚。为 OFF 时,只回滚产生错误的Transact-SQL 语句,而事务将继续进行处理。编译错误(如语法错误)不受 SET XACT_ABORT 的影响。
对于大多数 OLE DB 提供程序(包括 SQL Server),隐性或显式事务中的数据修改语句必须将 XACT_ABORT 设置为 ON。
SET XACT_ABORT 的设置是在执行或运行时设置,而不是在分析时设置。
示例 下例导致在含有其它 Transact-SQL 语句的事务中发生违反外键错误。在第一个语句集中产生错误,但其它语句均成功执行且事务成功
提交。在第二个语句集中,SET XACT_ABORT 设置为 ON。这导致语句错误使批处理终止,并使事务回滚。
CREATE TABLE t1 (a int PRIMARY KEY)
CREATE TABLE t2 (a int REFERENCES t1(a))
GO
INSERT INTO t1 VALUES (1)
INSERT INTO t1 VALUES (3)
INSERT INTO t1 VALUES (4)
INSERT INTO t1 VALUES (6)
GO
SET XACT_ABORT OFF
GO
BEGIN TRAN
INSERT INTO t2 VALUES (1)
INSERT INTO t2 VALUES (2) /* Foreign key error */
INSERT INTO t2 VALUES (3)
COMMIT TRAN
GO
SET XACT_ABORT ON
GO
BEGIN TRAN
INSERT INTO t2 VALUES (4)
INSERT INTO t2 VALUES (5) /* Foreign key error */
INSERT INTO t2 VALUES (6)
COMMIT TRAN
GO
SAVE TRANSACTION
在事务内设置保存点。
语法 SAVE TRAN [ SACTION ] { savepoint_name | @savepoint_variable }
参数 savepoint_name
是指派给保存点的名称。保存点名称必须符合标识符规则,但只使用前 32 个字符。
@savepoint_variable
是用户定义的、含有有效保存点名称的变量的名称。
必须用 char、varchar、nchar 或 nvarchar 数据类型声明该变量。 注释
用户可以在事务内设置保存点或标记。保存点定义如果有条件地取消事务的一部分,事 务可以返回的位置。如果将事务回滚到保存点,则必须(如果需要,使用更多的 Transact-SQL 语句和 COMMIT TRANSACTION 语句)继续完成事务,或者必须(通过将事务回滚到其起始点)完全取消事务。若要取消整个事务,请使用 ROLLBACK TRANSACTION transaction_name 格式。这将撤消事务的所 有语句和过程。
Note:1: 在由 BEGIN DISTRIBUTED TRANSACTION 显式启动或从本地事务升级而来的分布式事务中,不支持 SAVE TRANSACTION。
2:当事务开始时,将一直控制事务中所使用的资源直到事务完成(也就是锁定)。当将事务的一部分回滚到保存点时,将继续控制资源直到事务完成(或者回滚全部事务)。
例子:begin transaction
save transaction A
insert into demo values('BB','B term')
rollback TRANSACTION A
create table demo2(name varchar(10),age int)
insert into demo2(name,age) values('lis',1)
commit transaction
ROLLBACK TRANSACTION
将显式事务或隐性事务回滚到事务的起点或事务内的某个保存点。
语法
ROLLBACK [ TRAN [ SACTION ]
[ transaction_name | @tran_name_variable | savepoint_name | @savepoint_variable ] ]
参数
transaction_name
是给 BEGIN TRANSACTION 上的事务指派的名称。transaction_name 必须符合标识符规则,但只使用事务名称的前 32 个字符。嵌套
事务时,transaction_name 必须是来自最远的 BEGIN TRANSACTION 语句的名称。
@tran_name_variable
是用户定义的、含有有效事务名称的变量的名称。必须用 char、varchar、nchar 或 nvarchar 数据类型声明该变量。
savepoint_name
是来自 SAVE TRANSACTION 语句的 savepoint_name。savepoint_name 必须符合标识符规则。当条件回滚只影响事务的一部分时使 用savepoint_name。
@savepoint_variable
是用户定义的、含有有效保存点名称的变量的名称。必须用 char、varchar、nchar 或 nvarchar 数据类型声明该变量。
注释 ROLLBACK TRANSACTION 清除自事务的起点或到某个保存点所做的所有数据修改。ROLLBACK 还释放由事务控制的资源。
不带 savepoint_name 和 transaction_name 的 ROLLBACK TRANSACTION 回滚到事务的起点。嵌套事务时,该语句将所有内层事务回滚到 最远的 BEGIN TRANSACTION 语句。在这两种情况下,ROLLBACK TRANSACTION 均将 @@TRANCOUNT 系统函数减为 0。ROLLBACK
TRANSACTION savepoint_name 不减少 @@TRANCOUNT。
Note:
ROLLBACK TRANSACTION 语句若指定 savepoint_name 则不释放任何锁。
在由 BEGIN DISTRIBUTED TRANSACTION 显式启动或从本地事务升级而来的分布式事务中,ROLLBACK TRANSACTION 不能
引用savepoint_name。在执行 COMMIT TRANSACTION 语句后不能回滚事务。
在事务内允许有重复的保存点名称,但 ROLLBACK TRANSACTION 若使用重复的保存点名称,则只回滚到最近的使用该保存点名称的SAVE TRANSACTION。
在存储过程中,不带 savepoint_name 和 transaction_name 的 ROLLBACK TRANSACTION 语句将所有语句回滚到最远的BEGINTRANSACTION。在存储过程中,ROLLBACK TRANSACTION 语句使 @@TRANCOUNT 在触发器完成时的值不同于调用该存储过程时的@@TRANCOUNT 值,并且生成一个信息。该信息不影响后面的处理。
如果在触发器中发出 ROLLBACK TRANSACTION:将回滚对当前事务中的那一点所做的所有数据修改,包括触发器所做的修改。
触发器继续执行 ROLLBACK 语句之后的所有其余语句。如果这些语句中的任意语句修改数据,则不回滚这些修改。执行其余的语句不会激发嵌套触发器。在批处理中,不执行所有位于激发触发器的语句之后的语句。每次进入触发器,@@TRANCOUNT 就增加 1,即使在自动提交模式下也是如此。(系统将触发器视作隐性嵌套事务。)
在存储过程中,ROLLBACK TRANSACTION 语句不影响调用该过程的批处理中的后续语句;
将执行批处理中的后续语句。在触发器中,ROLLBACK TRANSACTION 语句终止含有激发触发器的语句的批处理;
不执行批处理中的后续语句。
ROLLBACK TRANSACTION 语句不生成显示给用户的信息。如果在存储过程或触发器中需要警告,请使用 RAISERROR 或 PRINT 语句。RAISERROR 是用于指出错误的首选语句。
ROLLBACK 对游标的影响由下面三个规则定义:
当 CURSOR_CLOSE_ON_COMMIT 设置为 ON 时,ROLLBACK 关闭但不释放所有打开的游标。
当 CURSOR_CLOSE_ON_COMMIT 设置为 OFF 时,ROLLBACK 不影响任何打开的同步 STATIC 或 INSENSITIVE 游标不影响已完全填充的异步 STATIC 游标。将关闭但不释放任何其它类型的打开的游标。
对于导致终止批处理并生成内部回滚的错误,将释放在含有该错误语句的批处理内声明的所有游标。
不论游标的类型或 CURSOR_CLOSE_ON_COMMIT 的设置,所有游标均将被释放,其中包括在该错误批处理所调用的存储过程内声明的游标。在该错误批处理之前的批处理内声明的游标以规则 1 和 2 为准。死锁错误就属于这类错误。在触发器中发出的 ROLLBACK 语句也 自动生成这类错误。
权限
ROLLBACK TRANSACTION 权限默认授予任何有效用户。
例子:
begin transaction
save transaction A
insert into demo values('BB','B term')
rollback TRANSACTION A
-- select * into demo2 from demo1
create table demo2(name varchar(10),age int)
insert into demo2(name,age) values('lis',1)
rollback transaction
COMMIT TRANSACTION
标志一个成功的隐性事务或用户定义事务的结束。如果 @@TRANCOUNT 为 1,COMMIT
TRANSACTION 使得自从事务开始以来所执行的 所有数据修改成为数据库的永久部分,释放连接
占用的资源,并将 @@TRANCOUNT 减少到 0。如果@@TRANCOUNT 大于 1,则COMMIT
TRANSACTION 使 @@TRANCOUNT 按 1 递减。
只有当事务所引用的所有数据的逻辑都正确时,发出 COMMIT TRANSACTION 命令。
COMMIT WORK
标志事务的结束。
语法
COMMIT [ WORK ]
注释
此语句的功能与 COMMIT TRANSACTION 相同,但 COMMIT TRANSACTION 接受用户定义的事务
名称。这个指定或没有指定可选关键字WORK 的 COMMIT 语法与 SQL-92 兼容
例子:
begin transaction a
insert into demo values('BB','B term')
commit TRANSACTION A
隐性事务
当连接以隐性事务模式进行操作时,SQL Server将在提交或回滚当前事务后自动启动新事务。无须描述事务的开始,只需提交或
回滚每个事务。隐性事务模式生成连续的事务链。
在为连接将隐性事务模式设置为打开之后,当 SQL Server 首次执行下列任何语句时,都会自动启动一个事务:
ALTER TABLE
INSERT
CREATE
OPEN
DELETE
REVOKE
DROP
SELECT
FETCH
TRUNCATE TABLE
GRANT
UPDATE
在发出 COMMIT 或 ROLLBACK 语句之前,该事务将一直保持有效。在第一个事务被提交或回滚之后,下次当连接执行这些语句
中的任何语句时,SQL Server 都将自动启动一个新事务。SQL Server 将不断地生成一个隐性事务链,
直到隐性事务模式关闭为止
例子:
begin transaction
save transaction A
insert into demo values('BB','B term')
rollback TRANSACTION A
create table demo2(name varchar(10),age int)
insert into demo2(name,age) values('lis',1)
rollback transaction
-- 在 Create table demo2 时 SQL Server 已经隐式创建一个Trans,知道提交或回滚
嵌套事务处理:
1: Trans 嵌套,将内部的trans 合并到外部并形成一个Trans.
begin tran t1
----In the first trans .
Insert into demo2(name,age) values('lis',1)
---Second Trans begin transaction t2
insert into demo values('BB','B term')
commit transaction t2
----In the first trans .
Insert into demo2(name,age) values('lis',2)
rollback transaction t1
Note:
在一系列嵌套的事务中用一个事务名给多个事务命名对该事务没有什么影响。系统仅登记第一个(最外部的)事务名。回滚
到其它任何名字(有效的保存点名除外)都会产生错误。
事实上,任何在回滚之前执行的语句都没有在错误发生时回滚。这语句仅当外层的事务回滚时才会进行回滚。
例:内部事务回滚SQL server 报错。
begin tran t1
Insert into demo2(name,age) values('lis',1)
---Second Trans
--Server: Msg 6401, Level 16, State 1, Line 6
---Cannot roll back t2. No transaction or savepoint of that name was found.
begin transaction t2
insert into demo values('BB','B term')
rollback transaction t2
----In the first trans .
Insert into demo2(name,age) values('lis',2)
commit transaction t1
例: 内部事务提交SQL server 不会报错。
begin tran t1
Insert into demo2(name,age) values('lis',1)
---Second Trans no error
begin transaction t2
insert into demo values('BB','B term')
commit transaction t2
----In the first trans .
Insert into demo2(name,age) values('lis',2)
commit transaction t1
SQL Server 的隔离级别:
1: 设置TimeOut 参数
Set Lock_TimeOut 5000
被锁超时5秒将自动解锁
Set Lock_TimeOut 0
产立即解锁,返回Error 默认为-1,无限等待
2:
(SET TRANSACTION ISOLATION LEVEL
{ READ COMMITTED
| READ UNCOMMITTED
| REPEATABLE READ | SERIALIZABLE})
READ COMMITTED
指定在读取数据时控制共享锁以避免脏读,但数据可在事务结束前更改,从而产生不可重复读取或
幻像数据。该选项是SQL Server 的默认值。
避免脏读,并在其他session 在事务中不能对已有数据进行修改。共享锁。
READ UNCOMMITTED
执行脏读或 0 级隔离锁定,这表示不发出共享锁,也不接受排它锁。当设置该选项时,可以对数
据执行未提交读或脏读;在事务结束前可以更改数据内的数值,行也可以出现在数据集中或从数据
集消失。该选项的作用与在事务内所有语句中的所有表上设置 NOLOCK 相同。这是四个隔离级别中
限制最小的级别。
REPEATABLE READ
锁定查询中使用的所有数据以防止其他用户更新数据,但是其他用户可以将新的幻像行插入数据
集,且幻像行包括在当前事务的后续读取中。因为并发低于默认隔离级别,所以应只在必要时才使
用该选项。
SERIALIZABLE
在数据集上放置一个范围锁,以防止其他用户在事务完成之前更新数据集或将行插入数据集内。这
是四个隔离级别中限制最大的级别。因为并发级别较低,所以应只在必要时才使用该选项。该选项
的作用与在事务内所有 SELECT 语句中的所有表上设置 HOLDLOCK 相同。
mysql禁用autocommit,以及遇到的问题
mysql的autocommit(自动提交)默认是开启,其对mysql的性能有一定影响,举个例子来说,如果你插入了1000条数据,mysql会commit1000次的,如果我们把autocommit关闭掉,通过程序来控制,只要一次commit就可以了。
1,我们可以通过set来设置autocommit
- mysql> set global init_connect="set autocommit=0"; //提示你用权限更高的财户来设置
- ERROR 1227 (42000): Access denied; you need (at least one of) the SUPER privilege(s) for this operation
- mysql> set autocommit=0;
- Query OK, 0 rows affected (0.00 sec)
- mysql> select @@autocommit; //查看一下autocommit的设置
- +--------------+
- | @@autocommit |
- +--------------+
- | 0 |
- +--------------+
- 1 row in set (0.00 sec)
2,我们可以修改mysql的配置文件my.cnf来关闭autocommit
- [mysqld]
- init_connect='SET autocommit=0' //在mysqld里面加上这些内容
用第二种方法关,有一点要注意,连接mysql用户的权限不能大于启动mysql的用户的权限,不然init_connect='SET autocommit=0'根本不会启作用,也不会报任何错误,汗一个先。看以下实例
- zhangy@ubuntu:~$ mysql -umysql
- Welcome to the MySQL monitor. Commands end with ; or \g.
- Your MySQL connection id is 1
- Server version: 5.5.2-m2-log Source distribution
- Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
- mysql> select @@autocommit; //mysql是启动用户,关闭autocommit成功
- +--------------+
- | @@autocommit |
- +--------------+
- | 0 |
- +--------------+
- 1 row in set (0.00 sec)
- mysql> Ctrl-C -- exit!
- Aborted
- zhangy@ubuntu:~$ mysql -uroot
- Welcome to the MySQL monitor. Commands end with ; or \g.
- Your MySQL connection id is 2
- Server version: 5.5.2-m2-log Source distribution
- Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
- mysql> select @@autocommit; //用root财户启动,不成功。
- +--------------+
- | @@autocommit |
- +--------------+
- | 1 |
- +--------------+
- 1 row in set (0.00 sec)
这个会不会是mysql的bug呢?我在网上找了找这方面的问题,还真有。部分内容如下:
If a user has SUPER privilege, init_connect will not execute
(otherwise if init_connect will a wrong query no one can connect to server).
Note, if init_connect is a wrong query, the connection is closing without any errors
and next command will clause 'lost connection' error.
里面有一点说的很清楚If a user has SUPER privilege, init_connect will not execute,如果用户有更高级的权限,init_connect根本不会执行。
4 4GO
5 5SET ANSI_NULLS ON
6 6GO
7 7
8 8ALTER procedure myInsertTest
9 9
1010@job_desc varchar(50),
1111@min_lvl tinyint,
1212@max_lvl tinyint,
1313@id int,
1414@name varchar(40)
1515
1616as
1717
1818 begin tran
1919
2020--第一张表的插入语句
2121INSERT INTO dbo.jobs (job_desc, min_lvl,max_lvl) VALUES(@job_desc,@min_lvl,@max_lvl)
2222
2323 --第二张表的插入语句
2424 INSERT INTO test (id,name) values( @id,@name)
2525
2626--如果有一张表插入失败就回滚
2727 IF @@ERROR <> 0
2828 BEGIN
2929 ROLLBACK TRAN
3030
3131 RETURN 0
3232 END
3333
3434 else
3535 BEGIN
3636 COMMIT TRANSACTION
3737 RETURN 1
3838 END
3939
4040
4141GO
4242SET QUOTED_IDENTIFIER OFF
4343GO
4444SET ANSI_NULLS ON
4545GO
4646
BEGIN TRANSACTION--开始事务
DECLARE @errorSun INT --定义错误计数器
SET @errorSun=0 --没错为0
UPDATE a SET id=232 WHERE a=1 --事务操作SQL语句
SET @errorSun=@errorSun+@@ERROR --累计是否有错
UPDATE aa SET id=2 WHERE a=1 --事务操作SQL语句
SET @errorSun=@errorSun+@@ERROR --累计是否有错
IF @errorSun<>0
BEGIN
PRINT '有错误,回滚'
ROLLBACK TRANSACTION--事务回滚语句
END
ELSE
BEGIN
PRINT '成功,提交'
COMMIT TRANSACTION--事务提交语句
END
1.什么是事务:事务是一个不可分割的工作逻辑单元,在数据库系统上执行并发操作时事务是做为最小的控制单元来使用的。他包含的所有数据库操作命令作为一个整体一起向系提交或撤消,这一组数据库操作命令要么都执行,要么都不执行。
2.事务的语句
开始事物:BEGIN TRANSACTION
提交事物:COMMIT TRANSACTION
回滚事务:ROLLBACK TRANSACTION
3.事务的4个属性
①原子性(Atomicity):事务中的所有元素作为一个整体提交或回滚,事务的个元素是不可分的,事务是一个完整操作。
②一致性(Consistemcy):事物完成时,数据必须是一致的,也就是说,和事物开始之前,数据存储中的数据处于一致状态。保证数据的无损。
③隔离性(Isolation):对数据进行修改的多个事务是彼此隔离的。这表明事务必须是独立的,不应该以任何方式以来于或影响其他事务。
④持久性(Durability):事务完成之后,它对于系统的影响是永久的,该修改即使出现系统故障也将一直保留,真实的修改了数据库
4.事务的保存点
SAVE TRANSACTION 保存点名称 --自定义保存点的名称和位置
ROLLBACK TRANSACTION 保存点名称 --回滚到自定义的保存点
二事例
所谓事务是指一组逻辑操作单元,它使数据从一种状态变换到另一种状态。
包括四个特性:
1、原子性 就是事务应作为一个工作单元,事务处理完成,所有的工作要么都在数据库中保存下来,要么完全回滚,全部不保留
2、一致性 事务完成或者撤销后,都应该处于一致的状态
3、隔离性 多个事务同时进行,它们之间应该互不干扰.应该防止一个事务处理其他事务也要修改的数据时,
不合理的存取和不完整的读取数据
4、持久性 事务提交以后,所做的工作就被永久的保存下来
示例:创建一个存储过程,向两个表中同时插入数据
Create proc RegisterUser
(@usrName varchar(30), @usrPasswd varchar(30),@age int,@sex varchar(10), @PhoneNum varchar(20), @Address varchar(50) )
as begin
begin tran
insert into userinfo(userName,userPasswd) values(@usrName,@usrPasswd)
if @@error<>0
begin
rollback tran
return -1
end
insert into userdoc(userName,age,sex,PhoneNumber,Address)values(@Usrname,@age,@sex,@PhoneNum,@Address)
if @@error<>0
begin
rollback tran
return -1
end
commit tran
return 0
end
事务的分类
按事务的启动与执行方式,可以将事务分为3类:
显示事务
也称之为用户定义或用户指定的事务,即可以显式地定义启动和结束的事务。分布式事务属于显示事务
自动提交事务
默认事务管理模式。如果一个语句成功地完成,则提交该语句;如果遇到错误,则回滚该语句。
隐性事务
当连接以此模式进行操作时,sql将在提交或回滚当前事务后自动启动新事务。无须描述事务的开始,只需提交或回滚每个事务。它生成连续的事务链。
一、显示事务
通过begin transacton、commit transaction、commit work、rollback transaction或rollback work等语句完成。
1、启动事务
格式:begin tran 事务名或变量 with mark 描述
2、结束事务
格式:commit tran 事务名或变量 (事务名与begin tran中的事务名一致
或commit work 但此没有参数
3、回滚事务
rollback tran 事务名或变量 | savepoint_name | savepoint_variable
或rollback work
说明:清除自事务的起点或到某个保存点所做的所有数据修改
4、在事务内设置保存点
格式:save tran savepoint_name | savepoint_variable
示例:
use bookdb
go
begin tran mytran
insert into book
values(9,"windows2000',1,22,'出版社')
save tran mysave
delete book where book_id=9
rollback tran mysave
commit tran
go
select * from book
go
可以知道,上面的语句执行后,在book中插入了一笔记录,而并没有删除。因为使用rollback tran mysave 语句将操作回滚到了删除前的保存点处。
5、标记事务
格式:with mark
例:使用数据库标记将日志恢复到预定义时间点的语句
在事务日志中置入一个标记。请注意,被标记的事务至少须提交一个更新,以标记该日志。
BEGIN TRAN MyMark WITH MARK
UPDATE pubs.dbo.LastLogMark SET MarkTime = GETDATE()
COMMIT TRAN MyMark
按照您常用的方法备份事务日志。
BACKUP LOG pubs TO DISK='C:\Backups\Fullbackup.bak' WITH INIT
现在您可以将数据库恢复至日志标记点。首先恢复数据库,并使其为接受日志恢复做好准备。
RESTORE DATABASE pubs FROM DISK=N'C:\Backups\Fullbackup.bak' WITH NORECOVERY
现在将日志恢复至包含该标记的时间点,并使其可供使用。请注意,STOPAT在数据库正在执行大容量日志时禁止执行。
RESTORE LOG pubs FROM DISK=N'C:\Backups\Logbackup.bak' WITH RECOVERY,
STOPAT='02/11/2002 17:35:00'
5、不能用于事务的操作
创建数据库 create database
修改数据库 alter database
删除数据库 drop database
恢复数据库 restore database
加载数据库 load database
备份日志文件 backup log
恢复日志文件 restore log
更新统计数据 update statitics
授权操作 grant
复制事务日志 dump tran
磁盘初始化 disk init
更新使用sp_configure后的系统配置 reconfigure
二、自动提交事务
sql连接在begin tran 语句启动显式事务,或隐性事务模式设置为打开之前,将以自动提交模式进行操作。当提交或回滚显式事务,或者关闭隐性事务模式时,将返回到自动提交模式。
示例:
由于编译错误,使得三个insert都没执行
use test
go
create table testback(cola int primary key ,colb char(3))
go
insert into testback values(1,'aaa')
insert into testback values(2,'bbb')
insert into testback value(3,'ccc') /*符号错误*/
go
select * from testback
go
没有任何结果返回
三、隐式事务
通过 API 函数或 Transact-SQL SET IMPLICIT_TRANSACTIONS ON 语句,将隐性事务模式设置为打开。下一个语句自动启动一个新事务。当该事务完成时,再下一个 Transact-SQL 语句又将启动一个新事务。
当有大量的DDL 和DML命令执行时会自动开始,并一直保持到用户明确提交为止,切换隐式事务可以用SET IMPLICIT_TRANSACTIONS
为连接设置隐性事务模式.当设置为 ON 时,SET IMPLICIT_TRANSACTIONS 将连接设置为隐性事务模式。当设置为 OFF 时,则使连接返回到自动提交事务模式
语句包括:
alter table insert open create delete revoke drop
select fetch truncate table grant update
示例:
下面使用显式与隐式事务。它使用@@tracount函数演示打开的事务与关闭的事务:
use test
go
set nocount on
create table t1(a int)
go
insert into t1 values(1)
go
print '使用显式事务'
begin tran
insert into t1 values(2)
print '事务外的事务数目:'+cast(@@trancount as char(5))
commint tran
print '事务外的事务数目:'+cast(@@trancount as char(5))
go
print
go
set implicit_transactions on
go
print '使用隐式事务'
go
insert into t1 values*4)
print'事务内的事务数目:'+cast(@@trancount as char(5))
commint tran
print'事务外的事务数目:'+cast(@@trancount as char(5))
go
执行结果:
使用显示事务
事务内的事务数目:2
事务外的事务数目:1
使用隐式事务
事务内的事务数目:1
事务外的事务数目:0
四、分布式事务
跨越两个或多个数据库的单个sql server中的事务就是分布式事务。
与本地事务区别:必须由事务管理器管理,以尽量避免出现因网络故障而导致一个事务由某些资源管理器成功提交,但由另一些资源管理器回滚的情况。
sql server 可以由DTc microsoft distributed transaction coordinator 来支持处理分布式事务,可以使用 BEgin distributed transaction 命令启动一个分布式事务处理
分二阶段:
A 准备阶段
B 提交阶段
执行教程:
1、sql 脚本或应用程序连接执行启动分布式事务的sql语句
2、执行该语句的sql在为事务中的主控服务器
3、脚本或应用程序对链接的服务器执行分布式查询,或对远程服务器执行远程存储过程。
4、当执行了分布式查询或远程过程调用后,主控服务器将自动调用msdtc以便登记分布式事务中链接的服务器和远程服务器
5、当脚本或应用程序发出commit或rollback语句时,主控sql将调用msdtc管理两阶段提交过程,或者通知链接的服务器和远程服务器回滚其事务。
转载自:http://lhsblog01.blog.163.com/blog/static/102004519200811301349181/
从功能上划分,SQL语言可以分为DDL,DML和DCL三大类。
1. DDL(Data Definition Language)
数据定义语言,用于定义和管理 SQL 数据库中的所有对象的语言 ;
CREATE---创建表
ALTER---修改表
DROP---删除表
2. DML(Data Manipulation Language)
数据操纵语言,SQL中处理数据等操作统称为数据操纵语言 ;
INSERT---数据的插入
DELETE---数据的删除
UPDATE---数据的修改
SELECT---数据的查询
DCL(Data Control Language)
数据控制语言,用来授予或回收访问数据库的某种特权,并控制数据库操纵事务发生的时间及效果,对数据库实行监视等;
GRANT---授权。
ROLLBACK---回滚
COMMIT---提交。
提交数据有三种类型:显式提交、隐式提交及自动提交。下面分别说明这三种类型。
(1) 显式提交
用COMMIT命令直接完成的提交为显式提交。
(2) 隐式提交
用SQL命令间接完成的提交为隐式提交。这些命令是:
ALTER,AUDIT,COMMENT,CONNECT,CREATE,DISCONNECT,DROP,
EXIT,GRANT,NOAUDIT,QUIT,REVOKE,RENAME。
(3) 自动提交
若把AUTOCOMMIT设置为ON,则在插入、修改、删除语句执行后,
系统将自动进行提交,这就是自动提交。其格式为: SQL>SET AUTOCOMMIT ON;
COMMIT / ROLLBACK这两个命令用的时候要小心。 COMMIT / ROLLBACK 都是用在执行 DML语句(INSERT / DELETE / UPDATE / SELECT )之后的。DML 语句,执行完之后,处理的数据,都会放在回滚段中(除了 SELECT 语句),等待用户进行提交(COMMIT)或者回滚 (ROLLBACK),当用户执行 COMMIT / ROLLBACK后,放在回滚段中的数据就会被删除。
(SELECT 语句执行后,数据都存在共享池。提供给其他人查询相同的数据时,直接在共享池中提取,不用再去数据库中提取,提高了数据查询的速度。)
所有的 DML 语句都是要显式提交的,也就是说要在执行完DML语句之后,执行 COMMIT 。而其他的诸如 DDL 语句的,都是隐式提交的。也就是说,在运行那些非 DML 语句后,数据库已经进行了隐式提交,例如 CREATE TABLE,在运行脚本后,表已经建好了,并不在需要你再进行显式提交。
mysql禁用autocommit,以及遇到的问题
mysql的autocommit(自动提交)默认是开启,其对mysql的性能有一定影响,举个例子来说,如果你插入了1000条数据,mysql会commit1000次的,如果我们把autocommit关闭掉,通过程序来控制,只要一次commit就可以了。
1,我们可以通过set来设置autocommit
- mysql> set global init_connect="set autocommit=0"; //提示你用权限更高的财户来设置
- ERROR 1227 (42000): Access denied; you need (at least one of) the SUPER privilege(s) for this operation
- mysql> set autocommit=0;
- Query OK, 0 rows affected (0.00 sec)
- mysql> select @@autocommit; //查看一下autocommit的设置
- +--------------+
- | @@autocommit |
- +--------------+
- | 0 |
- +--------------+
- 1 row in set (0.00 sec)
2,我们可以修改mysql的配置文件my.cnf来关闭autocommit
- [mysqld]
- init_connect='SET autocommit=0' //在mysqld里面加上这些内容
用第二种方法关,有一点要注意,连接mysql用户的权限不能大于启动mysql的用户的权限,不然init_connect='SET autocommit=0'根本不会启作用,也不会报任何错误,汗一个先。看以下实例
- zhangy@ubuntu:~$ mysql -umysql
- Welcome to the MySQL monitor. Commands end with ; or \g.
- Your MySQL connection id is 1
- Server version: 5.5.2-m2-log Source distribution
- Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
- mysql> select @@autocommit; //mysql是启动用户,关闭autocommit成功
- +--------------+
- | @@autocommit |
- +--------------+
- | 0 |
- +--------------+
- 1 row in set (0.00 sec)
- mysql> Ctrl-C -- exit!
- Aborted
- zhangy@ubuntu:~$ mysql -uroot
- Welcome to the MySQL monitor. Commands end with ; or \g.
- Your MySQL connection id is 2
- Server version: 5.5.2-m2-log Source distribution
- Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
- mysql> select @@autocommit; //用root财户启动,不成功。
- +--------------+
- | @@autocommit |
- +--------------+
- | 1 |
- +--------------+
- 1 row in set (0.00 sec)
这个会不会是mysql的bug呢?我在网上找了找这方面的问题,还真有。部分内容如下:
If a user has SUPER privilege, init_connect will not execute
(otherwise if init_connect will a wrong query no one can connect to server).
Note, if init_connect is a wrong query, the connection is closing without any errors
and next command will clause 'lost connection' error.
里面有一点说的很清楚If a user has SUPER privilege, init_connect will not execute,如果用户有更高级的权限,init_connect根本不会执行。
- 从SQL语言的分类谈COMMIT和ROLLBACK的用法
- 从SQL语言的分类谈COMMIT和ROLLBACK的用法
- 从SQL语言的分类谈COMMIT和ROLLBACK的用法
- 从SQL语言的分类谈COMMIT和ROLLBACK的用法
- 从SQL语言的分类谈COMMIT和ROLLBACK的用法
- 从SQL语言的分类谈COMMIT和ROLLBACK的用法
- 从SQL语言的分类谈COMMIT和ROLLBACK的用法
- 从SQL语言的分类谈COMMIT和ROLLBACK的用法
- 从SQL语言的分类谈COMMIT和ROLLBACK的用法
- 从SQL语言的分类谈COMMIT和ROLLBACK的用法
- 从SQL语言的分类谈COMMIT和ROLLBACK的用法
- 从SQL语言的分类谈COMMIT和ROLLBACK的用法
- COMMIT和ROLLBACK的用法
- COMMIT和ROLLBACK的用法
- SQL事务用法begin tran,commit tran和rollback tran的用法
- SQL 事务 begin tran、commit tran、rollback tran 的用法
- JDBC的commit和rollback
- MYSQL的COMMIT和ROLLBACK
- String to Date jstl标签的fmt:formatDate格式化日期
- LCD以及参数设置问题
- tabbar的那些事
- 为什么做java的web开发我们会使用struts2,springMVC和spring这样的框架?
- linux常用命令(7):mv命令
- 从SQL语言的分类谈COMMIT和ROLLBACK的用法
- MapReduce模型
- java多线程之join()方法
- tenp
- 2952 Counting Sheep【dfs】
- 更改Ubuntu系统时间命令
- 2015.8.27 学习日记
- PCIE协议解析 synopsys IP Core 读书笔记(2)
- json格式字符串转集合