使用Ado.Net进行简单事务处理的四种实现及比较

一:处理方法和示例代码

代码说明:

Test1为一个简单的数据库表,有两个字段,id为整型是非空关键字;name为字符型。已初始化记录一条(11’);

先在需要在Test中插入两条记录,一个为(10,’10’);一个为(1,’10’);如果其中一个失败便回滚。由于第二条肯定会失败,所以如果事务处理成功,结果是Test1之中最后仍只有一条id1的记录。

//数据库手动事务处理方法一:

SqlConnection myConn1 = new SqlConnection(Class1.conn1 );

myConn1.Open();

SqlTransaction myTrans1 = myConn1.BeginTransaction();

SqlCommand myComm1 = new SqlCommand("insert into test1 values(10,'10')",myConn1);

myComm1.Transaction = myTrans1;

try

{

    int ret = myComm1.ExecuteNonQuery();

    if(ret != 1)    

        throw new ApplicationException("");

 

    myComm1.CommandText = "insert into test1 values (1,'1')";

    ret = myComm1.ExecuteNonQuery();

    if(ret != 1)    

        throw new ApplicationException("");

 

    myTrans1.Commit(); 

}

catch(Exception ex)

{   

    myTrans1.Rollback();   

}

finally

{

    myConn1.Close();     

}

//数据库手动事务处理方法二:

SqlConnection myConn1 = new SqlConnection(Class1.conn1 );

myConn1.Open();

SqlTransaction myTrans1 = myConn1.BeginTransaction();

SqlCommand myComm1 = new SqlCommand("insert into test1 values (10,'10')\r\ninsert into test1 values (1,'10')",myConn1);

myComm1.Transaction = myTrans1;

try

{

    int ret = myComm1.ExecuteNonQuery();

    if(ret != 2)    

        throw new Exception("");

    myTrans1.Commit(); 

}

catch(Exception ex)

{   

    myTrans1.Rollback();   

}

finally

{

    myConn1.Close();     

}

//数据库手动事务处理方法三:

SqlConnection myConn1 = new SqlConnection(Class1.conn1 );

myConn1.Open();

SqlTransaction myTrans1 = myConn1.BeginTransaction();

 

string sql = @"begin tran

insert into test1 values(10,'10')

if (@@rowcount <> 1)

begin

          rollback tran

          return

end

 

insert into test1 values(1,'10')

if @@rowcount <> 1 

begin

          rollback tran

          return

end

 

commit tran";

SqlCommand myComm1 = new SqlCommand(sql,myConn1);

myComm1.Transaction = myTrans1;

try

{

    myComm1.ExecuteNonQuery();

   

    myTrans1.Commit(); 

}

catch(Exception ex)

{   

    myTrans1.Rollback();   

}

finally

{

    myConn1.Close();   

}

//数据库手动事务处理方法四:

SqlConnection myConn1 = new SqlConnection(Class1.conn1 );

string sql = @"InsertProc";  //InsertProc为存储过程,代码同方法三中的SQL

SqlCommand myComm1 = new SqlCommand(sql,myConn1);

myComm1.CommandType = CommandType.StoredProcedure ;

try

{

myConn1.Open();

myComm1.ExecuteNonQuery();

}

catch(Exception ex)

{   

    //;

}

finally

{

    myConn1.Close();   

}

 

上述四种实现代码都可以成功完成该事务处理。

二.方法比较和分析

1.        方法1

描述:这是较为常见的业务逻辑事务处理方法。把处理过程分为几个子过程;让这几个子过程都关联同一个事务;只要有一个子过程失败了,便回滚。全部子过程成功执行,提交事务。

特点:代码非常“逻辑化”;但数据库往返次数多,且实现与业务绑定很死。

适用:业务逻辑不能通过一条SQL语句或后台存储过程完成;或在每一个子过程执行完后必须进行客户端处理的情况等。

2.        方法二:

描述:这是偷懒的写法,不太常用。如果可以拼凑为一个SQL语句来完成事务处理,也就可以适用后台存储过程做。

特点:代码简单;但数据库一次往返次,业务更改时只修改拼凑的SQL语句。

适用:最好不用。如果是不同数据资源之间的可偶尔用,如乡音卡系统中的发卡操作:发卡时需要先在本地系统数据库中插入一条发卡交易记录;插入一条新发卡信息记录;然后在智能网数据库中修改新卡状态。三个子过程处于同一个事务中,此时可以把操作本地系统数据库中的两个操作拼凑为一个SQL语句,简化执行过程,又保证可以再第三步成功后再提交事务。

3.        方法三:

描述:这是不推荐的写法。原因同2

特点:利用SQL脚本的事务控制;数据库一次往返,业务更改时只修改拼凑的SQL语句。

适用:最好不用。这种情况推荐适用存储过程完成。但有时候数据库存储过程太多了的时候,为了减轻数据库的负担或者是  第三方的数据库,无法在其数据库中创建存储过程的情况。

4.        方法四:

描述:这也是较为常见的写法。推荐使用。

特点:利用SQL存储过程的事务控制;数据库一次往返,业务更改时只修改后台存储过程;而不用修改代码。

适用:一般可以由后台完成的事务处理情况下都尽量用这种方法。需要注意的是如果存储过程超过一定数量,需要对存储过程的处理代码维护更改记录

posted on 2006-10-24 11:54  Jessica.kjm  阅读(910)  评论(0编辑  收藏  举报