当前位置: 首页 > 知识库问答 >
问题:

事务作用域未使用Async/Await回滚

鞠安民
2023-03-14

我在使用Async/Await时遇到了一个问题,无法使事务范围回滚。在没有事务作用域的情况下,一切都正常工作,但只要我有意造成异常(第二次迭代时插入的主键重复),就不会发生回滚(更新时)或任何与事务相关的错误。

  • 我还应该注意,除非连接字符串中包含“OLE DB Services=4”,否则我将收到错误:“ITransactionLocal接口不受'Microsoft.ACE.OLEDB12.0'提供程序支持。本地事务不可用。”

下面的按钮事件处理程序中的代码只是测试事务范围的一个示例。主要目标是能够异步更新事务中包含的循环中的多个表,这样我就可以避免UI死锁,并对循环期间可能发生的任何异常执行回滚。对我的问题的任何替代方案或建议都表示感谢,谢谢:)

private async void button1_Click(object sender, EventArgs e)
        {
            try
            {
                int customerCount = 150;  // First 150 rows of customer table
                TransactionScope transaction = null;

                using (OleDbConnection dbConn = new OleDbConnection(Provider = Microsoft.ACE.OLEDB.12.0; OLE DB Services=-4; Data Source = " + filePath))
                {
                    dbConn.Open();
                    using (transaction = new TransactionScope(TransactionScopeAsyncFlowOption.Enabled))
                    {
                        for (int i = 0; i < customerCount; i++)
                        {

                            // Update field indicating customer made an invoice
                            var taskName = sql.executeAsync("UPDATE Customer SET lastInvoiceDate = @date WHERE customerID = @custID", dbConn,
                                new OleDbParameter("@date", DateTime.Today),
                                new OleDbParameter("@custID", i));

                            // Insert new invoice - Breaks here
                            var taskInsert = sql.executeAsync("INSERT INTO Invoice VALUES (1, 'thisisatestinvoice', '$100.50')", dbConn);


                            await Task.WhenAll(taskName, taskInsert);
                        }
                    }

                    // All updates executed properly
                    transaction.Complete();
                }
            }
            catch (AggregateException exception)
            {
                foreach (Exception ex in exception.InnerExceptions)
                {
                    MessageBox.Show(ex.Message);
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }

public async Task executeAsync(string dbQuery, OleDbConnection dbConn, params OleDbParameter[] parameters)
        {
            var dbComm = new OleDbCommand(dbQuery, dbConn);

            if (parameters != null)
                dbComm.Parameters.AddRange(parameters);

            await dbComm.ExecuteNonQueryAsync().ConfigureAwait(false);
        }

共有1个答案

罗翔
2023-03-14

我无法使事务作用域工作,我不完全确定是什么问题,我认为是由于我在ACE.OLEDB12.0上,但我找到了OleDbTransaction的另一个替代方案,如果发生任何故障,它将回滚。

private async void button1_Click(object sender, EventArgs e)
    {
        try
        { 
            using (OleDbConnection dbConn = new OleDbConnection(SQLWrapper.CONNECT_STRING))
            {
                dbConn.Open();
                OleDbTransaction dbTrans = dbConn.BeginTransaction();

                var taskName = sql.executeAsync("UPDATE Config SET Busname = @name", dbConn, dbTrans,
                     new OleDbParameter("@name", "name"));

                var taskInsert = sql.executeAsync("INSERT INTO Callout VALUES (16, 'ryanistesting')", dbConn, dbTrans);

                await Task.WhenAll(taskName, taskInsert);
                dbTrans.Commit();
            }
        }
    }

    public async Task executeAsync(string dbQuery, OleDbConnection dbConn, OleDbTransaction dbTrans, params OleDbParameter[] parameters)
    {
        using (var dbComm = new OleDbCommand(dbQuery, dbConn))
        {
            if (parameters != null)
                dbComm.Parameters.AddRange(parameters);

            if (dbTrans != null)
                dbComm.Transaction = dbTrans;

            await dbComm.ExecuteNonQueryAsync().ConfigureAwait(false);
        }
    }
 类似资料:
  • 编辑:在测试用例5中,任务似乎处于状态。 我在.NET 4.5中使用System.net.http.HttpClient时遇到了一些奇怪的行为--其中“等待”调用的结果(例如)将永远不会返回。 只有在使用新的Async/Await语言功能和任务API的特定情况下才会出现这种情况--代码似乎总是在只使用延续时工作。

  • 它会返回我想要的结果。我还从https://stackoverflow.com/a/25899982/9367841尝试了这个 但不管用。

  • 问题内容: 为了熟悉,我在Chrome中尝试了以下代码: 但不保存结果(字符串);而是持有一个需要再次等待的。这段代码确实给了我响应字符串: 如何使用await从函数返回实际的响应字符串? 问题答案: 要么 要么 这只是编写相同逻辑的另一种方法。

  • > < li >我在组织的租户azure环境中部署了一个ASP.NET(4.5)网站。 < li >它具有从网络位置(我们称之为nas驱动器)上传/下载/删除文件(任何类型)的功能,例如\nas8782\xyz\abc\ < li> 上传/下载/删除工作正常(参见下面的代码)。我们用的是CloudSdk。由我们的Azure团队创建的Azure库。 nasClient.UploadAsync nas

  • 我有一个安装了ReactJS的NetCore2应用程序。 null VS代码抛出一个错误,告诉我异步只适用于。ts文件。另外,如果我在任何其他函数中使用await,我将得到一个错误,比如。 据我所知,async/await不仅仅是TS...(或者我错了?)。 谢了!

  • Async/await 是以更舒适的方式使用 promise 的一种特殊语法,同时它也非常易于理解和使用。 Async function 让我们以 async 这个关键字开始。它可以被放置在一个函数前面,如下所示: async function f() { return 1; } 在函数前面的 “async” 这个单词表达了一个简单的事情:即这个函数总是返回一个 promise。其他值将自动被