1

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

没有错误,但它不会 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:事务命令不在有效序列中。

我需要更多提示:)

4

2 回答 2

2

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

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

Advantage 数据库服务器支持TransactionScope ,但您需要启用MSDTC 服务,并且可能还需要启用 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
        }
    }
}
于 2012-08-14T14:29:23.327 回答
1

TransactionScope 是您的朋友!

交易范围

于 2012-08-14T13:54:38.237 回答