Dotnet 使用数据库事务的方法

        数据库的操作比较复杂,特别是插入等操作难免有错误,为了保证数据的完整性,在数据库操作中常常需要使用事务。通过事物来完成一组操作,一旦其中出现任何错误,可以回滚这一组操作,这样数据就不会因为操作中的某个失误而变得不完整。

        以SQL SERVERADO.NET为例,数据库中操作数据库比较多的是使用两种方法,一个是通过SqlCommand对象,另一种是SqlDataAdapter对象,下面分别介绍这两种情况下使用事务的方法。

一、使用SqlCommand操作数据库时候使用事务

因为使用起来比较方便,所以这种方法是使用比较多的方法,代码如下:

  SqlConnection conn = new SqlConnection(ConnectString);//定义一个SqlConnection

  conn.Open();

  SqlTransaction trans = conn.BeginTransaction();//获得conn的TranSaction

    //定义一组操作Command

SqlCommand cmd1 = new SqlCommand();

SqlCommand cmd2 = new SqlCommand();

//设置command的属性

cmd1.Connection = conn;

cmd1.CommandText = cmdText;

cmd.Transaction = trans;

cmd2.Connection = conn;

cmd2.CommandText = cmdText;

cmd2.Transaction = trans;

 //操作

try

{

cmd1.ExecuteNonQuery();

cmd2.ExecuteNonQuery();

trans.Commit();                           

       }

   //如果出现错误,回滚操作

catch {

trans.Rollback();

       throw;

    }

二、使用SqlDataAdapter操作数据库时候使用事务

SqlDataAdapter的操作使用事务不如SqlCommand 普遍,但有时也要使用。一般都是SqlDataAdapter的Update 方法的时候需要回滚,方法如下:

 public bool Update(DataSet ds,string strSql,SqlTransaction theTrans,SqlConnection conn)

 public bool Update(DataSet ds,string strSql,SqlTransaction theTrans,SqlConnection conn)

{

SqlDataAdapter sda = new SqlDataAdapter(strSql,conn);

//使用命令生成器生成Command

SqlCommandBuilder scb = new SqlCommandBuilder(sda);

sda.SelectCommand.Transaction = theTrans;

//使用事务

sda.DeleteCommand.Transaction = theTrans;

sda.UpdateCommand.Transaction = theTrans;

sda.InsertCommand.Transaction = theTrans;

       dsCommand.Update(data);

if ( data.HasErrors )

                     {

                            data.Tables[0].GetErrors()[0].ClearErrors();

                            return false;

                     }

                     else

                     {

                            data.AcceptChanges();

                            return true;

                     }

}

  调用事务

SqlTransaction theTrans = conn.BeginTransaction(IsolationLevel.Serializable);

try{

theobject.Update(data,sqlStr,theTrans,conn);

theTrans.Commit(IsolationLevel.ReadCommitted);

}

catch

{

theTrans.RollBack();

throw;

}

三、使用COM+的事务功能

在分层设计的系统中,以上两种方法都应该在数据层的内部完成,而使用系统Com+的事务功能则可以把事务放到高层中进行,这样操作起来更加灵活。不过按照系统分层的原则,数据层的事情最好不要放到其他层中进行,所以除非必要,这种处理方式应该尽量避免。

 从EnterpriseServices.ServicedComponent继承类

 先添加引用System.EnterpristServices

namespace xxx

{

using System;

    using System.Reflection;

using System.Runtime.InteropServices;      

using System.EnterpriseServices; 

 

 [Transaction(System.EnterpriseServices.TransactionOption.Required)]//指定事务类型

 [ClassInterface(ClassInterfaceType.AutoDispatch)] //指定要生成的类的接口类型

 [ObjectPooling(MinPoolSize=4, MaxPoolSize=4)] //指定对象池

public class MyBusiness : ServicedComponent {

protected override bool CanBePooled() {

                                          return true;

                   }

[AutoComplete]   //标记为自动完成方法

public int  InsertData(DataSet ds)

{

}

     }

     }

 }

上面的类中的InsertData方法就是一个完整的事务,方法中的操作可以保持完整性,可以把一组数据操作放在这儿执行。这种操作不是单独对数据库适用,只是数据库操作也可以使用这种方法来完成一组事务,而且对多个数据库的同步来说,这是比较好的一种选择。

四、  使用SeviceConfig来完成事务

对比上面的ServicedComponent来说,使用SeviceConfig比较方便。使用ServicedComponent的程序集需要强名称,而且这个程序集所引用的程序集也必须是强名称。当然不是说强名称不好,但很多人有时候在发布前的开发调试阶段可能把这一步就先空着,等到发布的时候再加上强名称。还有,似乎在Web程序使用自己开发的Com+总是有些问题,不知道哪儿配置错了,反正我现在就是这样,每次修改都需要用regsvcs/u 把程序集发注册掉,然后重新生成程序集,再使用regsvcs 注册,然后用gacutil/i 添加到 GAC(Global Assembly Cache),不然的话使用SevicedComponent派生出来的类就有问题。好了,现在终于可以不用ServicedComponent了,可以使用SeviceConfig了,SeviceConfig的好处就是可以使用Service但是又不需要把它绑定到组件中去。但是,别高兴太早,一个不幸的消息就是SeviceConfig只能在Windows 2003下面使用,除非你保证自己开发的程序只运行在Windows2003平台下,否则你还是老老实实的使用前面几种方法吧。闲言少叙,我们还是来看看怎么用吧。

 

using System.EnterpriseServices;

 public class  MyClass

{

         ServiceConfig config = new ServiceConfig();

         config.Transaction = TransactionOption.Required;

         ServiceDomain.Enter(config);

         try

         {

              // 需要事务处理的代码

               ContextUtil.SetComplete();

         }

         catch(Exception e)

         {

            ContextUtil.SetAbort();

         }

         finally

         {

            ServiceDomain.Leave();

         }

}
 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值