事务范围(Transaction Scope)和手动定义事务之间的区别?

3

嗨,我正在阅读有关使用事务范围的内容。以前,我习惯于在单个DB类中进行事务处理,如下所示:

try
            {
                con.Open();
                tran = con.BeginTransaction();
                OleDbCommand myCommand1 = new OleDbCommand(query1, con);
                OleDbCommand myCommand2 = new OleDbCommand(query2, con);
                myCommand .Transaction = tran;
                // Save Master
                myCommand1.ExecuteNonQuery();

                // Save Childred
                myCommand2.ExecuteNonQuery();

                // Commit transaction 
                tran.Commit();

            }
catch (OleDbException ex)
                {
                    tran.Rollback();
                    lblError.Text = "An error occured " + ex.ToString();
                }

                finally
                {
                    if (con != null)
                    {
                        con.Close();
                    }

                }

但是现在我知道,我可以通过使用事务范围对象并使用单独的数据库类,在业务逻辑层内执行事务。

   public static int Save(Employee myEmployee)
    {
      using (TransactionScope myTransactionScope = new TransactionScope())
      {
        int RecordId = EmpDB.Save(myEmployee);

        foreach (Address myAddress in myEmployee.Addresses)
        {
          myAddress.EmployeeId = EmployeeId;
          AddressDB.Save(myAddress);
        }

        foreach (PhoneNumber myPhoneNumber in myEmployee.PhoneNumbers)
        {
          myPhoneNumber.EmployeeId = EmployeeId;
          PhoneNumberDB.Save(myPhoneNumber);
        }

        myTransactionScope.Complete();

        return EmployeeId;
      }
    }

哪种是推荐的编码方式,为什么?使用Transaction Scope是否安全?它是否是最新的做法?我对这两种方法感到困惑。

提前感谢。

1个回答

1
事务范围的一个好处是您不需要try/catch块。您只需在范围上调用Complete以提交事务,如果发生异常,则会自动回滚。
您还可以使用其他能够参与事务的组件,而不仅仅是DB连接。这是因为组件(包括连接)在当前线程上查找事务。正是通过对此调用创建的事务。
using (TransactionScope myTransactionScope = new TransactionScope())

谢谢Daniel Dyson。这看起来非常简单,需要编写的代码很少。如果每个DB层函数Address.Save();,Email.Save();,Employee.Save();都有自己的连接和命令,它会无缝地工作吗?就像在我的第二个例子中一样。 - Zo Has
抱歉,这是一个很难直接回答的问题,需要进行测试。好消息是测试应该很容易。 - Daniel Dyson
这很难说,哪一种是最推荐的做法以及为什么? - Zo Has
Transaction Scope 是更加简洁的代码,并且提供了将其他组件包含到范围内的能力,而 con.BeginTransaction 则不具备此功能。这已经足够让我使用它了。在这种情况下,实际发送到数据库的 DB 事务是相同的,但谁知道您将来可能想要添加什么到事务中,例如记录到另一个数据库或发送电子邮件。 - Daniel Dyson
谢谢提供的信息,如果在每个数据库类中使用存储过程,并在最后使用COMMIT将数据提交,那么它会提交数据吗?或者无论存储过程的指令如何,只要出现失败就会自动回滚? - Zo Has

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接