.NET 事务范围选项

发布于 2024-10-19 21:44:07 字数 627 浏览 4 评论 0原文

我是 C# 新手。所以我只是想知道是否有人可以帮助我弄清楚 C# 如何与 transactionscope 一起工作?因为我对它的定义有点困惑。不过,让我稍微解释一下我的问题。这样您就会了解我想要实现的目标。

我为三个不同的数据集声明了三个表适配器,如下所示:

logTableAdapter logAdap = new logTableAdapter();
measTableAdapter measAdap = new measTableAdapter();
valueTableAdapter valueAdap = new valueTableAdapter();

导入数据的过程是:

  1. 首先,我通过 logAdap.insert() 方法插入一个日志条目。
  2. 循环遍历 Excel 文件以获取测量值并开始通过 measAdap.insert() 方法插入。
  3. 对于每个测量,我通过 valueAdap.insert() 方法插入值。

所以我的问题是 - 因为测量和value 具有嵌套关系。如何创建嵌套的 transactionscope &当任何地方发生错误(测量插入/值插入)时,我只想回滚我所做的一切。也就是说,我只想回到插入日志条目之前的点。

I am a newbie in C#. So i was just wondering if anybody can help me figure out how C# works with transactionscope? Because i am a little confused by the definition of it. However, let me explain about my problem a little bit. So that you will get to know what i am trying to achieve.

I have three table adapter declared for three different dataset like this:

logTableAdapter logAdap = new logTableAdapter();
measTableAdapter measAdap = new measTableAdapter();
valueTableAdapter valueAdap = new valueTableAdapter();

The process to import data is:

  1. First I insert a log entry via logAdap.insert() method.
  2. Loop through an excel file to grab the measurements and starts inserting via measAdap.insert() method.
  3. Foreach measurement i am inserting values via valueAdap.insert() method.

So my question is - since measurement & value has a nested relationship. How can I create a nested transactionscope & when an error occur anywhere (measurement insertion / value insertion) i just want to rollback everything i did. That is i just want to go back to the point before the i inserted the log entry.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

对风讲故事 2024-10-26 21:44:07

引用这篇恰当命名的文章:权威TableAdapters + 事务博客文章

如果您在一个 TransactionScope 内处理多个操作,即单个 TransactionScope 内的“GetData”和“Update”,或者一个 TransactionScope 内的两个 Update,您将有效地打开到单个数据库的两个 SqlConnection,从而不必要地提升从 LTM 到 MSDTC 的交易。作为最佳实践,始终仅将单个操作包装在 TransactionScope 内。如果您选择将多个操作包装在单个 TransactionScope 内,则在这种情况下您必须通过扩展分部类定义来自行管理连接生存期。也就是说,下面的代码会导致交易推进——

using (TransactionScope tsc = new TransactionScope())
{
    tableAdap.GetData() ;
    //Do your transactional work.
    tableAdap.Update() ;
    tsc.Complete() ;
}

但是下面的代码就可以了 -

using (TransactionScope tsc = new TransactionScope())
{

    tableAdap.OpenConnection() ;
    tableAdap.GetData() ;

    //Do your transactional work.
    tableAdap.Update() ;
    tableAdap.CloseConnection() ;
    tsc.Complete() ;
} 

因此您只需要一个 TransactionScope,但有一些注意事项。这是要点,但我鼓励您阅读该博客文章。

TableAdapter 并不是最适合高完整性事务系统的数据访问方法。如果您需要更高的可靠性,您可能应该将操作编写为存储过程,并从 C# 代码中执行它。

Quoting this aptly named article: The definitive TableAdapters + Transactions blog post.

if you are working with plural operations inside one TransactionScope, i.e. “GetData” and “Update” both inside a single TransactionScope, or two Update’s within a TransactionScope, you will effectively open two SqlConnections to the single database, and thus unnecessarily promote the transaction from LTM to MSDTC. As a best practice, ALWAYS wrap only a singular operation inside a TransactionScope. Should you choose to wrap multiple operations inside a single TransactionScope, you must in that case manage connection lifetime yourself by extending the partial class definition. In other words, the following code will cause the transaction to promote –

using (TransactionScope tsc = new TransactionScope())
{
    tableAdap.GetData() ;
    //Do your transactional work.
    tableAdap.Update() ;
    tsc.Complete() ;
}

But the following code is just fine –

using (TransactionScope tsc = new TransactionScope())
{

    tableAdap.OpenConnection() ;
    tableAdap.GetData() ;

    //Do your transactional work.
    tableAdap.Update() ;
    tableAdap.CloseConnection() ;
    tsc.Complete() ;
} 

So you only need one TransactionScope, but with some caveats. Here is the gist, but I encourage you to read through the blog post.

TableAdapters aren't the most suitable data access methodology for high-integrity transactional systems. If you need more reliablity you should probably write your operation as a stored procedure, and execute it from you C# code.

城歌 2024-10-26 21:44:07

你不需要多个 TransactionScope,我认为你可以在同一个 TransactionScope 中完成所有操作。

you don't need more than one TransactionScope, you can do everything in the same one I think.

Smile简单爱 2024-10-26 21:44:07

因为我认为您正在寻找的是如何使用 TransactonScope,所以您的代码如下所示,稍微修改一下注释中的示例:

using( TransactionScope ts = new TransactionScope() ) { 
    try 
    { 
        logAdap.InsertLog(.....);

        foreach (.....)
        {
            measAdap.InsertMeas(.....); 
            foreach (.....)
            {
                valAdap.InsertVal(.....);
            }
        }

        // Complete the transaction
        ts.Complete();
    }
    catch (Exception ex) 
    { 
        // Your error handling here.
        // No need to rollback each table adapter. That along with all the 
        // transaction is done for you when exiting the using block without 
        // calling Complete() on the TransactionScope.
    }}

这种使用范围的方式称为隐式事务,您可以获得这篇 MSDN 文章对此进行了很好的概述:实现使用事务范围的隐式事务

话虽如此,fencliff 提到的是真的,因为您可能不想为您的场景打开多个连接,从而节省宝贵的数据库资源。

As I think that what you were looking for is how to use the TransactonScope, here is what your code would look like, modifying a little bit the example in your comment:

using( TransactionScope ts = new TransactionScope() ) { 
    try 
    { 
        logAdap.InsertLog(.....);

        foreach (.....)
        {
            measAdap.InsertMeas(.....); 
            foreach (.....)
            {
                valAdap.InsertVal(.....);
            }
        }

        // Complete the transaction
        ts.Complete();
    }
    catch (Exception ex) 
    { 
        // Your error handling here.
        // No need to rollback each table adapter. That along with all the 
        // transaction is done for you when exiting the using block without 
        // calling Complete() on the TransactionScope.
    }}

This way of using the scope is called implicit transactions and you can get a good overview of that in this MSDN article: Implementing an Implicit Transaction using Transaction Scope.

Having said that, what fencliff mentions is true, as you probably don't want to open multiple connections for your scenario, saving valuable database resources.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文