我是用数据访问类访问数据库的
下面是其中的一段程序
//
Database db=new Database();// Database是自定义数据访问类
sqlparameter[] sqlpara1={
           .............
            ............
                           }
db.RunProc("proc1",sqlpara1)//proc1是存储过程名,执行存储过程proc1,即对表1进行插入操作
sqlparameter[] sqlpara2={
           .............
            ............
                           }
db.RunProc("proc2",sqlpara2)//proc2是存储过程名,执行存储过程proc2,,即对表2进行插入操作可是有时会发生这种情况,当执行存储过程proc1,即对表1进行插入操作后,要执行proc2时,程序突然发生意外,抛出一个异常
这样子就发生了表1有数据,而表2没有数据的情况,请问大家这样子通常是要怎么处理好
有没有办法做到SQL事务那样进行回滚的???
虽然.NET程序中也有事务,但是好像对这样子的访问类起不了作用

解决方案 »

  1.   

    .net的事务中基于数据连接的,如果不在同一连接就把它做成COM+组件
      

  2.   

    try thisusing (OracleConnection conn = new OracleConnection(OracleHelper.CONN_STRING_NON_DTC))  

    conn.Open(); 
    using (OracleTransaction trans = conn.BeginTransaction())
    {
        try
        { 
    OracleHelper.ExecuteNonQuery(trans, CommandType.Text, SQL_INSERT_CUSTOMPAGE,parms);
                      Execute 2...
                      Execute 3...
                      Execute 4...
                      ...
    trans.Commit();
         } 
         catch 
         { 
    trans.Rollback();
    throw;
          } 
           }
           OracleHelper.CloseConnection(conn);
    } OracleHelper, I got it from Microsoft Applicaiton Block : http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnpag2/html/daab.aspSorry for English
      

  3.   

    Dim strSQLUpdate As String
            Dim strSQL As String
            Dim Conn As New SqlConnection(m_strConn)
            strSQLUpdate = "UPDATE BOMM SET COD_ITEM='" & Trim(CType(e.Item.Cells(1).Controls(0), TextBox).Text) & "'," & _
                                     "COD_PEPN='" & Trim(CType(e.Item.Cells(2).Controls(0), TextBox).Text) & "'," & _
                                     "COD_CUSTOM='" & Trim(CType(e.Item.Cells(3).Controls(0), TextBox).Text) & "'," & _
                                     "COD_NUM='" & Trim(CType(e.Item.Cells(4).Controls(0), TextBox).Text) & "'," & _
                                     "COD_TIME='" & Trim(CType(e.Item.Cells(5).Controls(0), TextBox).Text) & "'," & _
                                     "COD_B='" & Trim(CType(e.Item.Cells(6).Controls(0), TextBox).Text) & "'," & _
                                     "COD_PEP='" & Trim(CType(e.Item.Cells(7).Controls(0), TextBox).Text) & "'," & _
                                     "COD_ENTER='0' WHERE COD_ITEM='" & Trim(TextBox1.Text) & "' AND COD_B='" & Trim(TextBox2.Text) & "'"
            Dim Cmd As New SqlCommand        Try
                Conn.Open()
                cmd.Connection = conn
                Cmd.Transaction = Conn.BeginTransaction(IsolationLevel.ReadCommitted)
                Cmd.CommandText = strSQLUpdate
                Cmd.ExecuteNonQuery()            TextBox1.Text = Trim(CType(e.Item.Cells(1).Controls(0), TextBox).Text)
                TextBox2.Text = Trim(CType(e.Item.Cells(6).Controls(0), TextBox).Text)
                With Cmd.Parameters
                    .Add("@RTIME", SqlDbType.DateTime)
                    .Add("@COD_ITEM", SqlDbType.NVarChar)
                    .Add("@COD_B", SqlDbType.NVarChar)
                    .Add("@COD_PEP", SqlDbType.NVarChar)
                    .Add("@COD_NUM", SqlDbType.NVarChar)
                    .Add("@TYPE", SqlDbType.NVarChar)
                End With
                With Cmd
                    .Parameters("@RTIME").Value = Now
                    .Parameters("@COD_ITEM").Value = Trim(TextBox1.Text)
                    .Parameters("@COD_B").Value = TextBox2.Text
                    .Parameters("@COD_PEP").Value = CType(Session("UserName"), String).ToString
                    .Parameters("@COD_NUM").Value = CType(Session("Name"), String).ToString
                    .Parameters("@TYPE").Value = "修改主表"
                End With
                Dim strSql_His As String
                strSql_His = "INSERT INTO BOMHISTRY(RTIME,COD_ITEM,COD_B,COD_PEP,COD_NUM,TYPE) VALUES(@RTIME,@COD_ITEM,@COD_B,@COD_PEP,@COD_NUM,@TYPE)"
                Cmd.CommandText = strSql_His
                Cmd.ExecuteNonQuery()
                Cmd.Transaction.Commit()
            Catch ex As Exception
                Try
                    Cmd.Transaction.Rollback()
                    Response.Write("<script>javascript:alert('操作失敗,資料更新失敗,已經復原.請再試!!')</script>")
                Catch ee As Exception
                    Response.Write("<script>javascript:alert('操作失敗,請通知管理員!!')</script>")
                End Try
            Finally
                Conn.Close()
                Conn.Dispose()
                Cmd.Dispose()
            End Try
            DataGrid1.EditItemIndex = -1
            BindData2()
      

  4.   

    把两个存储过程合并为一个..然后用事务来处理..当有一个发生错误,则另一个会回转...没有写好的例子给你..临时写了个..你看看就明白了..begin transaction//事务处理开始insert into table(name1,name2..) values(1,2..)update table set name1=1,name2=2...commit transaction//事务处理结束事务处理..如果其中任何一条语句发生错误在begin transaction中则所有语句都不会得到执行.
      

  5.   

    .net开发者可以使用四种机制:l         数据库事务l         ADO.NET事务l         ASP.NET事务l         企业服务级事务每种机制在以下的几方面有各自的优势和劣势:性能、代码数量、部署设置。许多开发者都很熟悉数据库的事务,在这种情形下,中间层调用数据库的存储过程,存储过程中开始一个事务,如果每个语句都执行成功则提交,如果有错误发生时就会回滚。如果你的事务需要几个调用,例如,你需要插入多个定单明细到一个表中,但不想用一个xml文档或者传递一个很长的字符串,这些都需要在存储过程中被解析,你可以用ADO.NET事务机制。ADO.NET事务允许你在当前的连接上创建一个事务上下文,运行对数据库的多次调用,在最后或者提交或者回滚。ASP.NET事务是在Web应用程序的页面层工作,你只要简单的在页面属性中加一个” Transaction="Required”,这样在页面中的事件处理都作为页面整个事务的一部分,任何处理出现错误,则所有的处理都将回滚。企业服务型组件通过资源管理器和分布事务控制器(DTC)来实现事务,当ASP.NET,一个数据库的调用或者事务中涉及到的其他资源发生错误或者异常时,整个事务将被回滚,企业服务建立在COM+技术的基础上来处理事务,熟悉COM+的开发者应该理解企业服务。应该被提到实现一个事务的这些不同方式之间可能是互斥的,如果你混合使用数据库事务和企业服务事务,你就会得到一个错误,这是因为你会得到重复的提交,你在企业服务中可能提交一个在数据库事务中已经提交了的事务,这样已经没有事务上下文来进行提交动作了。同样的问题如在数据库事务中提交了一个事务,但在企业服务中却因为在系统中发生异常而回滚。
      

  6.   

    以下代码示例使用 Microsoft? SQL Server? 上的 ADO.NET 来演示事务逻辑。
    SqlConnection myConnection = new SqlConnection("Data Source=localhost;Initial Catalog=Northwind;Integrated Security=SSPI;");
    myConnection.Open();
    // 启动一个事务
    SqlTransaction myTrans = myConnection.BeginTransaction();
    // 为事务创建一个命令
    SqlCommand myCommand = new SqlCommand();
    myCommand.Connection=myConnection;
    myCommand.Transaction = myTrans;
    try
    {
    myCommand.CommandText = "Insert into Region (RegionID, RegionDescription) VALUES (100, "Description")";
    myCommand.ExecuteNonQuery();
    myCommand.CommandText = "Insert into Region (RegionID, RegionDescription) VALUES (101, "Description")";
    myCommand.ExecuteNonQuery();
    myTrans.Commit();
    Console.WriteLine("Both records are written to database.");
    }
    catch(Exception e)
    {
    myTrans.Rollback();
    Console.WriteLine(e.ToString());
    Console.WriteLine("Neither record was written to database.");
    }
    finally
    {
    myConnection.Close();
    }
     
      

  7.   

    请大家看清楚,下面的思路根本不行,套在数据访问类上就不行了,编译能通过,但是运行起来不行
    SqlConnection myConnection=SqlClass.GetConnection();//数据访问类的一个方法,返回一个Connection
    // 启动一个事务
    SqlTransaction myTrans = myConnection.BeginTransaction();
    try
    {
    String sqlstr="insert into.............";
    SqlClass.ExecuteSql(sqlstr1);//SqlClass.ExecuteSql(String sqlstr)是数据访问类的一个方法,能执行sqlstr语句对数据库的操作String sqlstr2="insert into.............";
    SqlClass.ExecuteSql(sqlstr2);myTrans.Commit();}
    catch(Exception e)
    {myTrans.Rollback();
    }
    finally
    {
    myConnection.Close();
    }
      

  8.   

    写一个存储过程,它先调用proc1,然后poc2。在运行这个存储过程是使用ADO.net的事物。评论:1. 太多人把业务逻辑做在应用程序代码中,这是有害的。当你改变永久数据时,数据库系统去判断、触发各种针对永久数据的逻辑程序。数据库上几句话往往可以省去应用程序中上百句,而且速度快十倍,特别是所有应用程序可以轻松地复用,免得一人一种方法把数据系统中的一致性搞的支离破碎。因此,这种“proc1触发proc2的逻辑”封装在数据库的一个简单接口中(过程中)是很好的。2. 数据库事务以上更复杂的所谓事务处理时不成熟的,需要程序员针对具体程序开发大量回滚控制代码、事务处理的正确性、可靠性的责任由程序员承担,系统仅提供接口没有实现真正实用的不需要程序员干预的机制。因此,一般来说,除非万不得已(比如网络结构限制),否则那些太高级的所谓事务处理其实是“成事不足”的,不能轻易用。
      

  9.   

    所谓的“数据访问类”限制了事务的使用,这些“数据访问类”就没有办法用。要么,他们须同时提供重载的传入Transaction类型参数的方法,要么就产生新的所谓“数据访问类”。
      

  10.   

    当同一个操作会对两个表有影响时,请用Transaction来处理。
    另外,如果数据发生“脏读”会影响数据完整性,也用Transaction来处理。
      

  11.   

    Transaction就已经可以了啊。你捕捉了已后,在catch里再抛出一个异常。这样上层就可以得到信息
      

  12.   

    数据库中数据的操作,除了查询之外,最好都用事务处理来保证数据的一致性。
    ado.net给我们提供了强大的数据库访问机制,但是每一次我们访问数据时都比较麻烦,况且我们开发信息系统时需要大量的数据库访问,为此,我做了一个用Ado.net访问数据库的类,可以说是Ado.net的集成及功能的扩展,访问数据只需要一个属性就可以为你返回DataTable数据表了,其中还包括事务处理的概念,可以大大的缩短我们快速编程的时间,由于篇幅的限制,我不能在这里把源代码贴处理,有需要的可以给我email,我发给你们。绝对免费,为了大家互相学习,交流!
      

  13.   

    sp1234在开玩笑。对于o/r mapping类的解决方案,没有可能吧那么多的东西放到stored procedure中
      

  14.   

    只能写到一个存储过程中,或直接在程序写sql语句。都要加上事务,成功提交,不成功回滚