SQL事务

1、事务概念
    事务是一种机制、是一种操做序列,它包含了一组数据库操做命令,这组命令要么所有执行,要么所有不执行。所以事务是一个不可分割的工做逻辑单元。在数据库系统上执行并发操做时事务是做为最小的控制单元来使用的。这特别适用于多用户同时操做的数据通讯系统。例如:订票、银行、保险公司以及证券交易系统等。
 
2、事务属性
事务4大属性:
1   原子性(Atomicity):事务是一个完整的操做。
2   一致性(Consistency):当事务完成时,数据必须处于一致状态。
3   隔离性(Isolation):对数据进行修改的全部并发事务是彼此隔离的。
4   持久性(Durability):事务完成后,它对于系统的影响是永久性的。
 
3、建立事务
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_currentMoney check(currentMoney>=1)
/**//*--插入测试数据--*/
insert into bank(customerName,currentMoney)
select '张三',1000 union
select '李四',1web

select * from bank
gosql

/**//*--使用事务--*/
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
gosqlserver

 

 

 

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

 
事务(Transaction)是并发控制的单位,是用户定义的一个操做序列。这些操做要么都作,要么都不作,是一个不可分割的工做单位。经过事务,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_ABORT   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
INSERT 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中一种简单的事务处理;如今经过一个典型的银行转帐的例子来讲明一下这两个例子的用法咱们先来看看sql存储过程是如何来完成事务的操做的:首先建立一个表:
 代码以下
create database aaaa --建立一个表,包含用户的账号和钱数gouse aaaacreate table bb( ID int not null primary key,  --账号 moneys money    --转帐金额)insert into bb values ('1','2000') --插入两条数据insert into bb values ('2','3000')用这个表建立一个存储过程:
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 --执行第二个操做,接受转帐的金额,增长  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存储过程,这样就相对比较简单
相关文章
相关标签/搜索