一、事务的概念和特点
事务(transaction)是恢复和并发控制的基本单位。
事务的特点:
原子性:事务是一个工作单元,要都成功,要么的失败
例子:A付款给B,A余额-100,B余额+100,只能都成功或者都失败,不能把A的钱扣了,而B的没加上
一致性:必须让数据库从一个一致状态到另一个一致状态
例子:还是上边的例子,A和B的总余额没有改变(保持了一致性)
隔离性:事务之间互不影响,并发执行的事务之间互不干扰(通过锁来实现的)
例子:A给B付款 和 C给B付款是两个事务,A付A的,C付C的,互不干扰。
持久性:事务对数据的改变时永久性的。
例子:A付款后,A的余额确实少了100,B的余额多了100(数据库中的记录确实改变了)
二、事务的使用
还是用付款的例子,先添加以下测试数据
--创建一个账户表,添加约束,余额(money)不小于零 create table Tb_bankAcount( Id int identity(1,1) primary key, Name nvarchar(20) not null, Money int not null ) alter table Tb_bankAcount add constraint CK_money CHECK(money>=0) --添加数据 insert into Tb_bankAcount values('A',200) insert into Tb_bankAcount values('B',200)
1、sql中使用事务
begin transaction --开启事务 declare @errorCount int=0;--记录错误的变量 update Tb_bankAcount set Money-=500 where Name='A' set @errorCount+=@@ERROR update Tb_bankAcount set Money+=500 where Name='B' set @errorCount+=@@ERROR if @errorCount>0 --有错误就回滚 rollback transaction else --没有错误提交 commit transaction
上边的代码执行时,由于不满足约束条件(Money>0),执行回滚
2、Ado.Net中使用事务
1 using (SqlConnection conn = new SqlConnection(connStr)) 2 { 3 //要执行的sql脚本 4 string sqlText = @"update Tb_bankAcount set Money-=100 where Name='A' 5 update Tb_bankAcount set Money+=100 where Name='B'"; 6 conn.Open(); 7 //创建事务 8 SqlTransaction tran = conn.BeginTransaction(); 9 using (SqlCommand com = new SqlCommand(sqlText, conn)) 10 { 11 try 12 { 13 //开启事务 14 com.Transaction = tran; 15 com.ExecuteNonQuery(); 16 //提交事务 17 tran.Commit(); 18 Console.WriteLine("事务执行成功"); 19 } 20 catch (Exception ex) 21 { 22 //回滚事务 23 tran.Rollback(); 24 Console.WriteLine(ex.Message); 25 } 26 } 27 }
上边的代码执行时,由于满足约束条件(Money>0),执行事务提交