SQL事务
一、事务概念
事务是一种机制、是一种操作序列,它包含了一组数据库操作命令,这组命令要么全部执行,要么全部不执行。因此事务是一个不可分割的工作逻辑单元。在数据库系统上执行并发操作时事务是作为最小的控制单元来使用的。这特别适用于多用户同时操作的数据通信系统。例如:订票、银行、保险公司以及证券交易系统等。
二、事务属性
事务4大属性:
1 原子性(Atomicity):事务是一个完整的操作。
2 一致性(Consistency):当事务完成时,数据必须处于一致状态。
3 隔离性(Isolation):对数据进行修改的所有并发事务是彼此隔离的。
4 持久性(Durability):事务完成后,它对于系统的影响是永久性的。
三、创建事务
T-SQL中管理事务的语句:
1 开始事务: begin transaction
2 提交事务:commit transaction
3 回滚事务: rollback transaction
事务分类:
1 显式事务:用begin transaction明确指定事务的开始。
2 隐性事务:打开隐性事务:set implicit_transactions on,当以隐性事务模式操作时,SQL Servler将在提交或回滚事务后自动启动新事务。无法描述事务的开始,只需要提交或回滚事务。
3自动提交事务:SQL Server的默认模式,它将每条单独的T-SQL语句视为一个事务。如果成功执行,则自动提交,否则回滚。
示例:张三转800元到李四帐户上。
use stuDB
go
--创建帐户表bank--
if exists(select* from sysobjects where name='bank')
drop table bank
create table bank
(
customerName char(10), --顾客姓名
currentMoney money --当前余额
)
go
/**//*--添加约束,帐户不能少于元--*/
alter table bank add
constraint CK_currentMoneycheck(currentMoney>=1)
/**//*--插入测试数据--*/
insert into bank(customerName,currentMoney)
select '张三',1000 union
select '李四',1
select * from bank
go
/**//*--使用事务--*/
use stuDB
go
--恢复原来的数据
--update bank set currentMoney=currentMoney-1000 where customerName='李'
set nocount on --不显示受影响的行数
print '查看转帐事务前的余额'
select * from bank
go
/**//*--开始事务--*/
begin transaction
declare @errorSum int --定义变量,用于累计事务执行过程中的错误
/**//*--转帐--*/
update bank set currentMoney=currentMoney-800 where customerName='张三'
set @errorSum=@errorSum+@@error --累计是否有错误
update bank set currentMoney=currentMoney+800 where customerName='李四'
set @errorSum=@errorSum+@@error --累计是否有错误
print '查看转帐事务过程中的余额'
select * from bank
/**//*--根据是否有错误,确定事务是提交还是回滚--*/
if @errorSum>0
begin
print '交易失败,回滚事务.'
rollback transaction
end
else
begin
print '交易成功,提交事务,写入硬盘,永久保存!'
commit transaction
end
go
print '查看转帐后的余额'
select * from bank
go
博客分类:
以下是SQL 回滚的语句:
方案一:
SET XACT_ABORT ON--如果产生错误自动回滚
GO
BEGIN TRAN
INSERT INTO A VALUES (4)
INSERT INTO B VALUES (5)
COMMIT TRAN
也 可以使用_ConnectionPtr 对象的方法: BeginTrans、CommitTrans、RollbackTrans,使用该系列函数判断 并回滚。一旦调用了 BeginTrans 方法, 在调用 CommitTrans 或 RollbackTrans 结束事务之前, 数据库将不再立即提交所作的任何更改。
方案二
BEGIN TRANSACTION
INSERT INTO A values (4) -----该表含有触发器,UPDATE其他表
IF @@error <> 0 --发生错误
BEGIN
ROLLBACK TRANSACTION
END
ELSE
BEGIN
COMMIT TRANSACTION
END
SET XACT_ABORT
指定当 Transact-SQL 语句产生运行时错误时,Microsoft® SQL Server™ 是否自动回滚当前事务。
语法
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 的设置是在执行或运行时设置,而不是在分析时设置
编写一个简单的sql事务 ,请教各位这样写事务是否正确
我有两个表需要更新
begin transaction
INSERT INTO YK (编号) SELECT 编号 FROM YK where ID=@ID --插入表1
update GQK set 数量= 结余数量*2 from GQK join YK on GQK.gid=YK.lid whereYK.ID=@ID --更新表2
if @@ERROR<>0
begin
rollback transaction
return
end
commit transaction
Castrandom,
使用事务需要特别注意一个地方:@@ERROR<>0只能判断当前语句的执行结果!
你这里begin transaction后面写了2条语句,如果第一条执行失败,而第二条执行成功,那么返回@@ERROR的结果是0(0表示成功);同样,如果第一条执行成功,而第二条执行失败,那么@@ERROR的结果是1哦。
@@error只能判断当前一条语句执行是否有错,为了判断事务中所有语句是否有错,建议对错误进行累计;
如:SET @errorSum=@errorSum+@@error,最后一步根据@errorSum来判断所有的语句是否成功。
Thanks, Yoyo Yu
-SQL2000:
--方法1、
begin TRANSACTION
--.........................定義變量
DECLARE @ID INT
SET @ID=10
INSERT INTO YK (编号) SELECT编号 FROMYK where ID=@ID--插入表1
if @@ERROR<>0
GOTO Error
update GQK set 数量= 结余数量*2 from GQK join YK on GQK.gid=YK.lid where YK.ID=@ID --更新表2
if @@ERROR<>0
GOTO Error
commit TRANSACTION
RETURN
ERROR:
rollback TRANSACTION
http://social.microsoft.com/Forums/en-US/sqlserverzhchs/thread/7170fff4-22ba-48b9-96cf-05dd6794528a
--方法2:
SET XACT_ABORT ON ;--指定當 Transact-SQL 陳述式產生執行階段錯誤時,SQL Server 是否自動回復目前的交易。
begin TRANSACTION
--.........................定義變量
DECLARE @ID INT
SET @ID=10
INSERT INTO YK (编号) SELECT编号 FROMYK where ID=@ID--插入表1
update GQK set 数量= 结余数量*2 from GQK join YK on GQK.gid=YK.lid where YK.ID=@ID --更新表2
COMMIT TRANSACTION
--SQL2005以上版本用
BEGIN TRY
BEGIN TRAN
--.........................定義變量
DECLARE @ID INT
SET @ID=10
INSERT INTO YK (编号) SELECT编号 FROMYK where ID=@ID--插入表1
update GQK set 数量= 结余数量*2 from GQK join YK on GQK.gid=YK.lid where YK.ID=@ID --更新表2
COMMIT TRAN
END TRY
BEGIN CATCH
DECLARE @Error NVARCHAR(2000)
SET @Error=ERROR_MESSAGE()
ROLLBACK TRAN
RAISERROR 50001 @Error
END CATCH