您的位置:首页 > 数据库

SQL 事务

2015-07-24 23:54 239 查看
首先声明,以下是个人见解,如有错误望指出,先谢谢!

我们知道数据库(SQL) 的事务,现在我讲讲我的大概了解:

数据库的事务使用基本语法:

begin try
begin tran [tranName]
--语句
commit tran [tranName]
end try
begin catch
rollback tran [tranName]
end catch


[] 表示可有可无,

try catch 我就不说了。 数据库执行事务成功与否 看的是计数,即 begin tran 和 commit tran 的计数。当计数一样就成功,不成功报如下错误:

EXECUTE 后的事务计数指示 BEGIN 和 COMMIT 语句的数目不匹配。上一计数 = 1,当前计数 = 2 , 只要是两个计数不一样,就会出现错误

一般写事务就是一层,所以 有没有事务名一样,当事务有多层(存储过程调用存储过程,循环调用存储过程(存储过程都是带事务的)) 这时候事务名是很重要的

简单说一下,当有A(含事务) 存储过程调用B(含事务)存储过程,如果 B 事务不指定事务名,当B 回滚的时候会将 A 的存储过程 计数也回滚,导致两个计数不一致,

如果 B 事务指定事务名,将不会影响 A 事务的计数。这就是有事务名和没有事务名的区别,一句话:有事务名就是当前事务,没有事务名就是整个事务。

C# 中有个 SqlTransaction 类,怎么使用我就不说了,这个类的事务和数据库的事务是一样的,他们公用同一个进程,也就是说 在C# 类里有事务,在执行的SQL里

也有事务,当把SQL里的事务提交(没有指明事务名的情况) 会导致 C# 当前的 事务对象为null.

这里顺便说下: set xact_abort on 这个设置是指 出错后自动回滚,一般用在存储过程中。

下面给一个事务嵌套的例子:

表结构:

CREATE TABLE [dbo].[Test](
[Id] [int] IDENTITY(1,1) NOT NULL,
[Name] [nvarchar](5) NOT NULL
) ON [PRIMARY]


子事务:

CREATE procedure [dbo].[CreateSubTran]
(
@Name nvarchar(50),
@Status int output
)
as
begin
begin try
print '准备开始:'+CAST(@@TRANCOUNT AS VARCHAR(50))
begin tran currentTran
save tran preTran
print '事务开始:'+CAST(@@TRANCOUNT AS VARCHAR(50))
insert test(Name)
values(@Name)
set @Status=1
print '执行成功:'+CAST(@@TRANCOUNT AS VARCHAR(50))
commit tran currentTran
print 'commit'
end try
begin catch
print '出错回滚前:'+CAST(@@TRANCOUNT AS VARCHAR(50))
if(@@TRANCOUNT>0)
begin
rollback tran preTran
end
set @Status=-1
commit tran currentTran
print '出错回滚后:'+CAST(@@TRANCOUNT AS VARCHAR(50))
return 0
end catch

end


 父事务:

create proc CreateParentTran
as
begin
declare @result int
begin try
begin tran
exec  [CreateSubTran] 'sdfsd',@result output
commit tran
end try
begin catch
rollback tran
end catch
end


 注意: 最外层事务可以不用指定事务名,嵌套事务必须指定事务名,上面已经讲的很清楚。



如图结果:事务开始的计数必须与结束的计数是一样的



当事务执行回滚后,当前的计数 就等于事务还未开始前的计数。

 
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: