Asp.net c#,回滚或提交多个进程后

时间:2012-08-14 13:52:23

标签: asp.net asp.net-mvc advantage-database-server

我希望在多个进程之后使用Rollback()或commit()函数。

没有错误,但它没有提交()来更新数据库。

这是我的示例代码,

public void startTransaction(){
    using(Ads_A_Connection = new AdsConnection(Ads_A_connection_string))
    using(Ads_B_Connection = new AdsConnection(Ads_B_connection_string))
    {
        Ads_A_Connection.Open();
        Ads_B_Connection.Open();

        AdsTransaction aTxn = Ads_A_Connection.BeginTransaction();
        AdsTransaction bTxn = Ads_B_Connection.BeginTransaction();

        try{
            string aResult = this.process1(Ads_A_Connection);       
            this.process2(Ads_B_Connection, aResult);       
            this.process3(Ads_A_Connection. Ads_B_Connection);

            aTxn.Commit();
            bTxn.Commit();
            // there is no error, but it couldn't commit.
        }catch(Exception e){
            aTxn.Rollback();
            bTxn.Rollback();
        }
    }
}

public string process1(conn){
    // Insert data
    return result;
}

public void process2(conn. aResult){
    // update
}

public void process3(aConn, bConn){
    // delete
    // update
}

我想,这是因为没有使用范围。因为我试图将所有代码放入 startTransaction()方法,然后它工作。但它看起来太脏了。

如何在多个(METHOD)过程之后使用rollback()或commit()?

任何人都知道,请告诉我。

谢谢!

[编辑]

我只是在连接之前添加TransactionScope,

using (TransactionScope scope = new TransactionScope())
{
   using(Ads_A_Connection = new AdsConnection(Ads_A_connection_string))
   using(Ads_B_Connection = new AdsConnection(Ads_B_connection_string))
   {
     .
     .

但它出错了,它说" 错误5047:事务命令没有有效序列。"

我需要更多提示:)

2 个答案:

答案 0 :(得分:2)

为了扩展Etch提到的内容,他们在手动管理连接上的事务时遇到了几个问题:

  • 您需要围绕方法传递SQL连接
  • 完成后需要手动记住提交或回滚
  • 如果您要在交易下管理多个连接,则应该使用DTC或XA将事务注册到Distributed / 2阶段事务中。

使用Advantage数据库服务器的TransactionScopes are supported,尽管您需要启用MSDTC service并且还可能启用XA合规性。

请注意,我假设.NET客户端具有某种连接池机制的优势 - 这使得获取连接的成本非常轻。

最终,这意味着您的代码可以重构为以下内容,这样更容易维护:

private void Method1()
{
    using(Ads_A_Connection = new AdsConnection(Ads_A_connection_string))
    {
        Ads_A_Connection.Open();
        string aResult = this.process1(Ads_A_Connection);       
    } // Can logically 'close' the connection here, although it is actually now held by the transaction manager
}

private void Method2()
{
    using(Ads_B_Connection = new AdsConnection(Ads_B_connection_string))
    {
        Ads_B_Connection.Open();
        this.process2(Ads_B_Connection, aResult);       
    } // Can logically 'close' the connection here, although it is actually now held by the transaction manager
}


public void MyServiceWhichNeedToBeTransactional(){
    using(TransactionScope ts = new TransactionScope()) { // NB : Watch isolation here. Recommend change to READ_COMMITTED
        try{
           Method1();
           Method2();
           ts.Complete();
        }
        catch(Exception e){
          // Do Logging etc. No need to rollback, as this is done by default if Complete() not called
        }
    }
}

答案 1 :(得分:1)

TransactionScope是你的朋友!

TransactionScope