与Dapper,Oracle vs MS中的C#交易

发布于 2025-01-31 03:08:22 字数 1007 浏览 0 评论 0原文

我有一个我使用了一段时间的代码:

using Dapper.Contrib;
using Dapper.Contrib.Extensions;
...
        async Task DBStuff()
        {
            OracleConnection conn = new OracleConnection();
            //SqlConnection conn = new SqlConnection();
            await conn.OpenAsync();
            using (var tran = await conn.BeginTransactionAsync())
            {
                var sql = "insert stuff...";
                await conn.ExecuteAsync(sql);
            }
        }

它可完美地工作。但是,当我将连接从oracleconnection切换到SQLConnection时,我会在Conn.executeasync(SQL)中获得此错误: “ BegineXecutenOnquery需要命令在分配给命令的连接处于待处理的本地交易中时必须进行交易

…… (SQL,Transaction:Tran)

是否有办法使其像OracleConnection一样,即不必每次通过交易?

根据这篇文章(使用C#和C#和ODP.NET )Oracle不需要或使用其他交易设置:

oraclecommand自动“重用”交易是 当前在命令的OracleConnection上活动

I have this code which I used for some time:

using Dapper.Contrib;
using Dapper.Contrib.Extensions;
...
        async Task DBStuff()
        {
            OracleConnection conn = new OracleConnection();
            //SqlConnection conn = new SqlConnection();
            await conn.OpenAsync();
            using (var tran = await conn.BeginTransactionAsync())
            {
                var sql = "insert stuff...";
                await conn.ExecuteAsync(sql);
            }
        }

It works flawlessly. However when I switch the connection from OracleConnection to SqlConnection suddenly I get this error at conn.ExecuteAsync(sql):
"BeginExecuteNonQuery requires the command to have a transaction when the connection assigned to the command is in a pending local transaction... "

I can get rid of error if I pass the transaction to every conn.ExecuteXXX() like this:

conn.ExecuteAsync(sql, transaction: tran)

Is there a way to make it work like with OracleConnection, i.e without having to pass the transaction every time?

According to this post (Performing an Oracle Transaction using C# and ODP.NET) Oracle doesn't need or use additional transaction settings:

The OracleCommand automatically "reuses" the transaction that is
currently active on the command's OracleConnection

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

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

发布评论

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

评论(1

小鸟爱天空丶 2025-02-07 03:08:22

最后,我决定放下Dapper Transactions并使用TransactionsCope。
我正在写这篇文章,所以也许会帮助某人,并纠正我对此主题发现的一些评论。该代码看起来像这样:

using System.Transactions;
...

        using (var transactionScope = new TransactionScope(TransactionScopeAsyncFlowOption.Enabled))            
        {
            SqlConnection conn = new SqlConnection();
            var sql = "insert stuff...";
            await conn.ExecuteAsync(sql);

            transactionScope.Complete();
        }

请注意,要使用异步方法,必须使用transactionscopeasyncflowoption.mabled选项。
该代码比Dapper代码具有多个优点:

  • 简单
  • 不需要明确打开该连接
  • 不需要将事务参数传递给conn.executexxxxxxxxxxxxxxxxt()方法
  • 不需要明确的回滚
  • ,可与分布式交易一起使用(用于我,但也许不是每个人,因为它需要MSDTC)
  • 与多个连接一起工作

In the end I decided to drop Dapper transactions and use TransactionScope.
I'm writing this so maybe will help someone and to correct some comments that I found about this subject. The code will look like this:

using System.Transactions;
...

        using (var transactionScope = new TransactionScope(TransactionScopeAsyncFlowOption.Enabled))            
        {
            SqlConnection conn = new SqlConnection();
            var sql = "insert stuff...";
            await conn.ExecuteAsync(sql);

            transactionScope.Complete();
        }

Note that in order to work with Async methods TransactionScopeAsyncFlowOption.Enabled option must be used.
The code has several advantages over Dapper code:

  • it's simpler
  • doesn't require to explicitly open the connection
  • doesn't need a transaction argument passed to conn.ExecuteXXX() methods
  • doesn't require explicit rollback
  • works with distributed transactions (a big plus for me but maybe not for everybody because it requires MSDTC)
  • works with multiple connections
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文