ADO.NET 2.0中的Transaction对象

来源:互联网 发布:淘宝加入不了购物车 编辑:程序博客网 时间:2024/06/07 00:01
  Transaction(事务):用于执行多个SQL语句组成的语句序列,并且除非全部语句执行成功,变动才会产生,否则回滚到事务执行前的状态。
  关于事务有一个经典示例,要多A帐户扣除100元钱给B帐户。这需要两步来完成:
  1、扣除A帐户100元:UPDATE TABLE SET AccountAmount=AccountAmount-100 WHERE AccountID=A
  2、给B帐户增加100元:UPDATE TABLE SET AccountAmount=AccountAmount+100 WHERE AccountID=B
  这样,就完成了所需的操作。但是,这里有一个问题,因为此语句是顺序执行的,如果执行了1语句,但是,就在此时,系统出现了异常,使得2名句没有能够正确执行。那么,就会出现A帐户被扣除了100元钱,但B帐户却没有收到钱。恐怕,这是A与B都不希望看到的结果
  于是,必须有一种机制,来使得这两个语句像一个语句一样,要么,全部执行成功,要么全部不执行。这样,就有了Transaction(事务)机制来完成这种需求。
  以下是在SQL Server中关于事物的一个简单示例:
Begin Transaction
  UPDATE TABLE SET AccountAmount=AccountAmount-100 WHERE AccountID=A
  UPDATE TABLE SET AccountAmount=AccountAmount+100 WHERE AccountID=B
IF @@Error>0
  Rollback
ELSE
  Commit
  这里,通过Begin Transaction来开始一个事务。事务一直到Rollback或者Commit结束。这中间,如果出现错误,则@@Error的值会>0,此时,Rollback(回滚)到事务执行之前的状态。否则就Commit(确认)此事务——改写数据库里的内容。
  呵呵,写了这么多没提到Transaction对象。其实,最终Transaction对象最终还是形成一个类似的SQL语句块。
  Transaction对象属于ADO.NET中与数据库类别有关的对象。以SQL Server为例,其使用的是System.Data.SqlClient中的SqlTransaction类来完成Transaction机制。我们建立一个Transaction对象来完成以上任务:
SqlTransaction trans;//声明一个事务,此时,事务尚未开始
SqlConnection conn=new SqlConnection("...."); //构造一个SqlConnection对象
SqlCommand cmd=conn.CreateCommand();
cmd.CommandText="UPDATE TABLE SET AccountAmount=AccountAmount-100 WHERE AccountID=A";
try
{
  conn.Open();//打开连接
  trans=conn.BeginTransaction();//相当于SQL语句:begin transaction
  cmd.Transaction=trans;//把Command关联到事务中
  cmd.ExecuteNonQuery();//执行第一个SQL语句
  cmd.CommandText="UPDATE TABLE SET AccountAmount=AccountAmount+100 WHERE AccountID=B";//修改语句
  cmd.ExecuteNonQuery();//执行第二个SQL语句
  trans.Commit();//正常提交(此时,数据库数据才真正的改变)
}
catch(Exception)
{
  trans.Rollback();//出现异常,回滚到begin transaction的之前的状态
}
finally
{
   conn.Close();//关闭连接
}
从此例中可以看出,Transaction对象是在Conneciton对象建立以后,才能通过Connection对象的BeginTransaction()方法来建立。事实上,此时,必须保持事务与数据库的连接,如果在连接建立之前调用BeginTransaction()方法,会得到一个异常。
  在实际的系统中,针对于一个数据库而言,通常会使用在存储过程中应用事务的机制,即直接利用RDBMS提供的事务机制。这样子,一个事务就必须在一个存储过程中完成,不会出现由于用户的某些操作导致数据库连接长期被打开的状况。并且,这样也可以减少命令传输量与传输次数。
  那么,ADO.NET 2.0里为什么仍然提供了Transaction机制呢?因为ADO.NET 2.0里的事务更为灵活,例如,你可以在执行了语句1以后,对客户端状态进行一定的改变,然后,再执行语句2,最后提交整个事务。这对于存储过程中事务是做不到的。
  事务执行的时候,会有使用一些锁,来处理并行(concurrency)。那么,在事务运行的时候,到底使用什么锁,Transaction对象中的Isolation属性对此进行了规定,用以制定并行情况下的锁策略。
  待续...
原创粉丝点击