[转]sql server transaction

正文转自:

http://www.2cto.com/database/201208/146734.html

sql事务(Transaction)用法介绍及回滚实例

 

事情(Transaction)是并发控制的单位,是用户定义的1个操作类别。这几个操作照旧都做,要么都不做,是一个不可分割的工作单位。通过作业,SQL
Server能将逻辑相关的一组操作绑定在一道,以便服务器保持数据的完整性

 

当对多少个表实行更新的时候,某条实施破产。为了保持数据的完整性,须要采取工作回滚。 

来得设置工作

 代码如下

begin try   www.2cto.com  

begin transaction 

insert into shiwu (asd) values (‘aasdasda’); 

commit transaction 

end try 

begin catch 

select ERROR_NUMBER() as errornumber 

rollback transaction 

end catch

隐式设置工作

 代码如下

set implicit_transactions on; — 运转隐式事务 

go 

begin try 

insert into shiwu (asd) values (‘aasdasda’); 

insert into shiwu (asd) values (‘aasdasda’); 

commit transaction; 

end try 

begin catch 

select ERROR_NUMBER() as errornumber 

rollback transaction; –回滚事务 

end catch 

set implicit_transactions off; –关闭隐式事务 

go

来得事务以下语句不可能应用,隐式事务可以

 代码如下

alter database; 

backup;   www.2cto.com  

create database; 

drop database; 

reconfigure; 

restore; 

update statistics;

来得事务可以嵌套使用

 代码如下

–创制存款和储蓄进程 

create procedure qiantaoProc 

@asd nchar(10) 

as 

begin 

begin try 

begin transaction innerTrans 

save transaction savepoint –创立工作保存点 

insert into shiwu (asd) values (@asd); 

commit transaction innerTrans 

end try 

begin catch 

rollback transaction savepoint –回滚到保存点 

commit transaction innerTrans 

end catch 

end 

go 

begin transaction outrans 

exec qiantaoProc ‘asdasd’; 

rollback transaction outrans

思想政治工作嵌套,回滚外层事务时,即使嵌套内的作业已经回滚过则会有尤其。此时亟需利用工作保存点。如下实例

SQL事务回滚

内定当   Transact-SQL   语句产生运维时不当时,Microsoft®   SQL  
Server™   是还是不是自动回滚当前事务

方案一:

 代码如下

SET   XACT_ABO哈弗T   ON–假使发生错误自动回滚

GO

BEGIN   TRAN

INSERT   INTO   A   VALUES   (4)

INSERT   INTO   B   VALUES   (5)

COMMIT   TRAN  www.2cto.com  

也得以选取_ConnectionPtr 对象的措施:
BeginTrans、CommitTrans、RollbackTrans,使用该体系函数判断并回滚。一旦调用了
BeginTrans 方法, 在调用 CommitTrans 或 RollbackTrans 截止工作此前,
数据库将不再马上提交所作的别的改变。

方案二

 代码如下

BEGIN TRANSACTION

INSECR-VT INTO A   values  (4)   —– 该表含有触发器,UPDATE其余表

IF @@error <> 0  –发生错误

   BEGIN

     ROLLBACK TRANSACTION

         

   END

ELSE

   BEGIN

     COMMIT TRANSACTION

       

   END

 

sql事务结合asp.net三种用法

在sql server+ .net
开发环境下,有二种办法能够不辱职责业务的操作,保持数据库的数据完整性;一个就是用sqlserver/42850.htm
target=_blank
>sql存储进度,另三个正是在ADO.NET中一种简单的事务处理;现在通过3个博闻强志的银行转账的例子来证实一下那三个例子的用法大家先来探视sql存款和储蓄进度是何等来达成工作的操作的:首先创建2个表:

 代码如下

create database aaaa –创立多个表,包罗用户的帐号和钱数gouse aaaacreate
table bb( ID int not null primary key,  –帐号 moneys money  
 –转账金额)insert into bb values (‘1′,’两千’) –插入两条数据insert
into bb values (‘2′,’三千’)用那个表创制3个仓库储存进度:

create procedure mon –成立存款和储蓄进度,定义多少个变量

@toID int,    –接收转账的账户

@fromID int ,  –转出本身的账户

@momeys money –转账的金额

as

begin tran –初步施行工作

 

update bb set moneys=moneys-@momeys where ID=@fromID
-执行的首先个操作,转账出钱,减去转出的金额

update bb set moneys=moneys+@momeys where ID=@toID
–推行第1个操作,接受转账的金额,扩展  www.2cto.com  

 

if @@error<>0 –判断如若两条语句有任何一条出现错误

begin rollback tran –起头施行工作的回滚,恢复生机的转化开始在此以前情况

return 0

end

go

 

else   –怎么样两条都实施成功

begin commit tran 执行这几个业务的操作

return 1

end

go

 

接下去看看C#.net 是怎么着调用这些蕴藏进程的:

   

 代码如下

protected void Button1_Click(object sender, EventArgs e)

    {

        SqlConnection con =new SqlConnection(@”Data
Source=.SQLEXPRESS;database=aaaa;uid=sa;pwd=jcx”); //连接字符串

        SqlCommand cmd = new SqlCommand(“mon”,con); //调用存款和储蓄进程

        cmd.CommandType = CommandType.StoredProcedure;

        con.Open();

        SqlParameter prar = new SqlParameter();//传递参数

        cmd.Parameters.AddWithValue(“@fromID”, 1);

        cmd.Parameters.AddWithValue(“@toID”, 2);

        cmd.Parameters.AddWithValue(“@momeys”,Convert.ToInt32(
TextBox1.Text) );

   www.2cto.com  

        cmd.Parameters.Add(“@return”, “”).Direction =
ParameterDirection.ReturnValue;//获取存款和储蓄进度的再次回到值

        cmd.ExecuteNonQuery();

        string value =
cmd.Parameters[“@return”].Value.ToString();//把重回值赋值给value

        if (value == “1”)

        {

            Label1.Text = “添加事业有成”;

        }

        else

        {

            Label1.Text = “添加退步”;

       }

}

本条也正是在储存进度里拉长事务,再来看看不在数据库写sql存款和储蓄进程,ADO.NET是怎么处管事人务的:

 代码如下

protected void Button2_Click(object sender, EventArgs e)

    {

        SqlConnection con = new SqlConnection(@”Data
Source=.SQLEXPRESS;database=aaaa;uid=sa;pwd=jcx”);

        con.Open();

        SqlTransaction tran =
con.BeginTransaction();//先实例SqlTransaction类,使用那些工作使用的是con
这几个一连,使用BeginTransaction那一个点子来先导施行这一个事情

        SqlCommand cmd = new SqlCommand();

        cmd.Connection = con;

        cmd.Transaction = tran;

        try

        {

             //在try{} 块里实施sqlcommand命令,

            cmd.CommandText = “update bb set moneys=moneys-‘” +
Convert.ToInt32(TextBox1.Text) + “‘ where ID=’1′”;

            cmd.ExecuteNonQuery();

            cmd.CommandText = “update bb set moneys=moneys+’ aa ‘ where
ID=’2′”;

            cmd.ExecuteNonQuery();

           
tran.Commit();//固然三个sql命令都执行成功,则实行commit那么些主意,执行那一个操作

   www.2cto.com  

            Label1.Text = “添加事业有成”;

        }

        catch

        {

            Label1.Text = “添加战败”;

           
tran.Rollback();//怎么着履行不成事,发生尤其,则履行rollback方法,回滚到事情操作起来在此以前;

        }

 

    }

那就是三个业务分化用法的简约例子,ADO.NET
事务处理的法门看起来相比较不难,但是他要运用同叁个接连来施行这一个操作,假设同时采纳多少个数据库来用二个事情执行,那样就相比繁琐,可是若是用sql存款和储蓄进程,那样就相对比较简单

 

 

http://www.cnblogs.com/fgynew/archive/2011/12/16/2290525.html

 

精研了下,发现sql server里面包车型客车explicit transaction依旧有点复杂的。以下是有个别总计:

·        
Commit transaction 会提交全数嵌套的transaction修改。不过倘使嵌套的transaction里面有rollback tran to save point, 那么save point之后的有的会revert掉。

delete from dbo.numbertable

begin tran out1

     insert into dbo.numbertable values(1)

     insert into dbo.numbertable values(2)

    

     begin tran
inn1

         
insert into
dbo.numbertable values(3)

         
insert into
dbo.numbertable values(4)

     save tran
inn1SavePoint

         
insert into
dbo.numbertable values(5)

     rollback tran
inn1SavePoint

     commit tran
inn1

commit tran out1

 

·        
@@TRANCOUNT能够用来记录当前session
transaction的个数,对于嵌套的transaction来讲,每趟begin transaction都让它加一,每便commit tran都会让它减一。所以在讲话里面能够由此select
@@TRANCOUNT 来检查当前是或不是在1个transaction里面。假若当前@@TRANCOUNT为0,那调用commit依旧rollback都会产出语句错误。在嵌套的transaction里面,rollback是很奇特的,它会一向把@@TRANCOUNT设置为0。

begin tran

begin tran

begin tran

print @@trancount

rollback tran

print @@trancount

 

SQL Server,·        
对于嵌套的transaction来讲,rollback的写法是很新鲜。借使嵌套,rollback
transaction前边是不可能带transaction的name的,要带也不得不是最外面包车型大巴transaction的name。Rollback只会放任全数嵌套transaction在rollback语句此前的改动。Rollback之后的创新如故提交就去了,原因在于:rollback之后,@@trancount为0,那么rollback之后的语句就不属于explicit transaction,
属于autocmmit transaction了,自动提交。

delete from dbo.numbertable

begin tran t1

     insert into dbo.numbertable values(1)

    

     begin tran
t2

         
insert into
dbo.numbertable values(2)

     rollback tran

     print ‘after rollback in
innert transaction, the transaction count is: ‘+cast(@@trancount, varchar(5))

     insert into dbo.numbertable values(3)

–commit
tran

select * from dbo.numbertable

 

·        
存款和储蓄进度里面也足以begin
transaction,如若调用的地点也begin
transaction,那么那种场合也属于嵌套transaction,假如在存款和储蓄进度里面rollback,获得的结果和地点一样。但是有有个别非凡的地方在与,执行存储进程截止的时候会相比起来施行sp的@@trancount和终止时候@@trancount的值,固然差别,它会交到二个新闻像“Transaction
count after EXECUTE indicates that a COMMIT or ROLLBACK TRANSACTION
statement is missing. Previous count = 1, current count = 0.”这么些给出的音讯并不会影响现在的推行。

CREATE PROCEDURE [dbo].[AddNumber]       

AS

BEGIN

     begin tran

         
insert into
dbo.numbertable values(1)

         
insert into
dbo.numbertable values(2)

         
insert into
dbo.numbertable values(3)

     rollback tran

END

delete from dbo.numbertable

begin tran out1

exec dbo.addnumber

print @@trancount

insert into dbo.numbertable
values(3)

select * from dbo.numbertable

 

·        
借使在sp里面rollback了,那到外满做commit, 可能rollback都是尚未效力还要出错了,因为嵌套的transaction内部transaction一旦调用了rollback,@@trancount就为0了,在外满commit,rollback直接出错。比如如下sp,笔者想像在最外面rollback,那就出错了,因为sp里面语句rollback了。表里面始终会插入值3。

delete from dbo.numbertable

begin tran out1

exec dbo.addnumber

print @@trancount

insert into dbo.numbertable
values(3)

rollback tran out1

select * from dbo.numbertable

 

·        
全部对于嵌套的transaction来讲,假使中间transaction一旦rollback,就会给外部的transaction留下一个大坑。为了消除这些为题,有二种缓解方案:

1.      
在外表的transaction里面检查@@trancount,如若这一个值跟你代码begin tran的能够一如既往,那表达内部transaction没有rollback,那能够继续commit可能rollback。

delete from dbo.numbertable

begin tran t1

     insert into dbo.numbertable values(1)

    

     begin transaction
t2

         
insert into
dbo.numbertable values(2)

     rollback tran

 

     if @@trancount = 1

     begin

         
insert into
dbo.numbertable values(3)

         
commit tran

     end

2.      
在具有的内部transaction里面,只好commit,无法rollback。即使必须rollback,那怎么做?save point就足以派上用场了。比如sp改成那规范:

ALTER PROCEDURE [dbo].[AddNumber]        

AS

BEGIN

     begin tran

     save tran
pp

         
insert into
dbo.numbertable values(1)

         
insert into
dbo.numbertable values(2)

         
insert into
dbo.numbertable values(3)

     rollback tran
pp

     commit tran

END

 

begin tran out1

exec dbo.addnumber

print @@trancount

insert into dbo.numbertable
values(3)

commit tran out1

 

 

 

 

相关文章