天高地厚

  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

【转载】事务的使用(ADO.NET和SQL SERVER)

Posted on 2013-05-23 13:17  天高地厚-GNU  阅读(168)  评论(0编辑  收藏  举报

最近几天,在做项目的过程中,写了一些存储过程用来处理一些业务逻辑,发现在数据库中只有很少几个存储过程,而我这边就一个很小的模块都要涉及到几张表的操作,写存储过程是最方便的,而且效率也是最高的。于是,我问了一下这边的负责人,他们之前开发的那些模块,怎么没有写几个存储过程?而负责人的给我的回答是,以后别人来维护,出现问题时,跟踪调试写存储过程不好调试。我不敢苟同这种说法。

  既然项目负责人不让用存储过程,那只能用代码实现这些业务逻辑了,我选择用ADO.NET中的事务。

  我要实现的功能是上传附件的功能,需要涉及到3张表,分别是附件表Appendix,报告基础表Report和零件表Part。另外还有一张表示Appendix与Report的中间表StatusManage。上传附件时,需要向appendix表中插入一条附加信息记录,同时在页面可以修改Report表和Part表中的数据,表关系如下图

 

保存按钮中的代码如下:

  /// <summary>
    /// 上传附件保存事件
    ///  modify by dlw 2010-07-01
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    protected void lbtnSave_Click(object sender, EventArgs e)
    {
        try
        {
            UpladFile();//这是将文件上传到服务器上的方法,可以不用考虑这个方法。

    //这是获取连接字符串的方法
            string conStr = Common.CommonDB.CreateConnection().ConnectionString;
            using (SqlConnection con = new SqlConnection(conStr))
            {
                con.Open();
                SqlTransaction tran;//定义事务
                SqlCommand com = con.CreateCommand();
                tran = con.BeginTransaction();//创建事务
                com.Transaction = tran;//为sqlcommand对象指定定义的事务
                try
                {
                    //插入一条新的附件记录
                    com.CommandText = string.Format(@"insert into dbo.PAB_Appendix (FlowID,[FileName],FilePath,FileRemark,UploadTime,Uploador)
                                             values('{0}','{1}','{2}','{3}','{4}','{5}')",
                                                      ViewState["FlowID"].ToString(),
                                                      FileUpload.FileName,
                                                      AppDomain.CurrentDomain.BaseDirectory + "UploadFile//",
                                                      "",
                                                      DateTime.Now.ToString(),
                                                      User.Identity.Name
                                                      );
                    com.ExecuteNonQuery();
                    //更新pab基础表中的数据
                    com.CommandText = string.Format(@"update dbo.PAB_ReportList set CarType='{0}',Fachabteilung='{1}',
                                        FOP_ID='{2}',FOP_Name='{3}',FactoryCode='{4}' where PAB_ReportID='{5}'",
                                                    ddlCarType.SelectedItem.Value.Trim(),//车型
                                                    ddlDept.SelectedItem.Value.Trim(),//科室
                                                    hiFop.Value,//fop
                                                    txtFOP.Text.Trim(),//
                                                    txtFactoryCode.Text.Trim(),//厂家
                                                    ViewState["PAB_ReportID"].ToString());
                    com.ExecuteNonQuery();
                    //更新主零件信息
                    com.CommandText = string.Format(@"update PAB_PartList set Part_Num='{0}' where PAB_PLID in
                                           (select PAB_PartList.PAB_PLID  from PAB_ReportList,PAB_PartList
                                            where PAB_ReportList.PAB_ReportID=PAB_PartList.PAB_ReportID
                                             and  PAB_PartList.isMainPart=1
                                             and PAB_ReportList.PAB_ReportID='{1}')",
                                                    txtMainPartNum.Text.Trim(),
                                                    ViewState["PAB_ReportID"].ToString());
                    com.ExecuteNonQuery();
                    tran.Commit();// 事务提交
                    Response.Write("<script>alert('上传成功!');returnValue=true;window.close();</script>");
                }
                catch (Exception ex)
                {
                    tran.Rollback();//事务回滚
                }
                finally
                {
                    tran.Dispose();//事务销毁
                }
            }
        }
        catch (Exception ex)
        {
            Response.Write("<script>alert('上传失败!')</script>");
        }
    }

上面的代码中,用红色标示出来的地方,是使用事务的地方。

总结一下,ADO.NET使用事务的格式是什么样子的呢? 把上面示例代码中用红色标示出来的代码提取出来,如下:

//这是获取连接字符串的方法
            string conStr = Common.CommonDB.CreateConnection().ConnectionString;
            using (SqlConnection con = new SqlConnection(conStr))
            {
                con.Open();
                SqlTransaction tran;//定义事务
                SqlCommand com = con.CreateCommand();
                tran = con.BeginTransaction();//开始一个本地事务
                com.Transaction = tran;//为sqlcommand对象指定定义的事务
                try
                {

       //TODO

        //处理一些业务逻辑
        tran.Commit();// 事务提交
                }
                catch (Exception ex)
                {
                    tran.Rollback();//事务回滚
                }
                finally
                {
                    tran.Dispose();//事务销毁
                }
            }

至此,用代码实现的业务逻辑就告一段落了。

刚开始的时候,我已经说过了,我已经用存储过程结合事务实现了上面的业务逻辑,下面把我用存储过程实现的业务逻辑给大家分享一下,希望对大家有一定的参考价值!

ALTER procedure [dbo].[SP_PAB_UploadAppendix]
(
 @FileName varchar(50),--上传附件名称
 @FilePath varchar(100),--上传附件路径
 @FileRemark varchar(200),--附件备注
 @Operator varchar(38),--操作人
 @CarType varchar(10),--车型
 @MainPartNum varchar(20),--主零件编号
 @Fachabteilung varchar(10),--科室
 @FOP_ID varchar(38),--负责人id
 @FOP_Name varchar(50),--负责人名称
 @FactoryCode Varchar(10),--厂家编号
 @FactoryName Varchar(100),--厂家名称
 @PAB_ReportID int,
 @StatusID int --
)
as
begin
 begin try
  begin tran --事务开始
   --获取与reportlist中status对应的flowid
   declare @FlowID int
   select @FlowID=PAB_StatusManage.FlowID from PAB_StatusManage
    where PAB_ReportID=@PAB_ReportID and StatusID=@StatusID
   --向附件表中插入数据
   insert into dbo.PAB_Appendix (FlowID,[FileName],FilePath,FileRemark,UploadTime,Uploador)
    values(@FlowID,@FileName,@FilePath,@FileRemark,getdate(),@Operator)
 
   --更新reportlist表中的数据
   update dbo.PAB_ReportList set CarType=@CarType,Fachabteilung=@Fachabteilung,
     FOP_Name=@FOP_Name,FactoryCode=@FactoryCode where PAB_ReportID=@PAB_ReportID
   --更新partlist表中主零件的数据
   
   if exists(select 1  from PAB_ReportList,PAB_PartList where PAB_ReportList.PAB_ReportID=PAB_PartList.PAB_ReportID and  PAB_PartList.isMainPart=1 and PAB_ReportList.PAB_ReportID=@PAB_ReportID)
   begin
    update PAB_PartList set Part_Num=@MainPartNum where PAB_PLID in
    (select PAB_PartList.PAB_PLID  from PAB_ReportList,PAB_PartList where PAB_ReportList.PAB_ReportID=PAB_PartList.PAB_ReportID and  PAB_PartList.isMainPart=1 and PAB_ReportList.PAB_ReportID=@PAB_ReportID)
   end

  commit tran--事务提交
 end try
 begin catch
  rollback tran--事务回滚
 end catch
end

上面红色标出的地方是使用事务的地方。

 总结一下,把红色部分代码提取出来,如下:

 begin try
    begin tran --事务开始

    --处理一些业务逻辑

    commit tran--事务提交
 end try
 begin catch
    rollback tran--事务回滚
 end catch