zoukankan      html  css  js  c++  java
  • 【转载】事务的使用(ADO.NET和SQL SERVER) 天高地厚

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

      既然项目负责人不让用存储过程,那只能用代码实现这些业务逻辑了,我选择用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

  • 相关阅读:
    Container Attached Storage: A primer
    1.3-Air302(NB-IOT)-新建lua文件和lua文件的变量,函数调用
    STM32+ESP8266+AIR202/302基本控制篇-114-功能测试-APP扫码绑定Air302(NB-IOT),并通过MQTT和Air302(NB-IOT)实现远程通信控制
    1.2-Air302(NB-IOT)-刷固件,下载和运行第一个lua程序
    1.1-Air302(NB-IOT)-硬件使用说明
    006-STM32+ESP8266+AIR202/302基本控制方案(阿里云物联网平台)-阿里云物联网平台加入规则引擎(云产品流转),让两个MQTT设备之间实现通信
    004-在阿里云物联网平台上动态注册设备(基于Android)
    30-STM32+W5500+AIR202基本控制篇-功能优化-MQTT服务器配置SSL单向认证(Linux系统)
    30-STM32+W5500+AIR202基本控制篇-功能优化-MQTT服务器配置SSL单向认证(.Windows系统)
    数据处理思想和程序架构: 单片机stm32的flash保存数据优化方案(让擦写次数达到上百万至上千万次)
  • 原文地址:https://www.cnblogs.com/net2012/p/3094682.html
Copyright © 2011-2022 走看看