首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >澄清sqlTransaction操作

澄清sqlTransaction操作
EN

Stack Overflow用户
提问于 2020-02-11 16:55:41
回答 4查看 48关注 0票数 0

我对事务的理解是,一个或多个SQL命令都将作为一个组执行。

现在,我正在阅读微软的文档,我不理解第一个try-catch异常块的目标。如果事务失败,我们为什么要尝试回滚事务。我的意思是,如果它失败了,那么我们不应该肯定DB中没有做任何更改(因为这是事务的目标)吗?我有什么不明白的?

代码语言:javascript
复制
private static void ExecuteSqlTransaction(string connectionString)
{
    using (SqlConnection connection = new SqlConnection(connectionString))
    {
        connection.Open();

        SqlCommand command = connection.CreateCommand();
        SqlTransaction transaction;

        // Start a local transaction.
        transaction = connection.BeginTransaction("SampleTransaction");

        // Must assign both transaction object and connection
        // to Command object for a pending local transaction
        command.Connection = connection;
        command.Transaction = transaction;

        try
        {
            command.CommandText =
                "Insert into Region (RegionID, RegionDescription) VALUES (100, 'Description')";
            command.ExecuteNonQuery();
            command.CommandText =
                "Insert into Region (RegionID, RegionDescription) VALUES (101, 'Description')";
            command.ExecuteNonQuery();

            // Attempt to commit the transaction.
            transaction.Commit();
            Console.WriteLine("Both records are written to database.");
        }
        catch (Exception ex)
        {
            // Logging exception details
            // Attempt to roll back the transaction.
            try
            {
                transaction.Rollback();
            }
            catch (Exception ex2)
            {
                // Logging exception details
            }
        }
    }
}
EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2020-02-11 17:40:43

根据您所链接的Microsoft文档:“事务在任何错误上都会回滚,或者如果它未经首次提交就被释放了。”我的重点。因此,我希望以下几点也能奏效:

代码语言:javascript
复制
private static void ExecuteSqlTransaction(string connectionString)
{
    using (SqlConnection connection = new SqlConnection(connectionString))
    {
        connection.Open();

        using (SqlCommand command = connection.CreateCommand())
        using (SqlTransaction transaction connection.BeginTransaction("SampleTransaction"))
        {
            // Must assign both transaction object and connection
            // to Command object for a pending local transaction
            command.Connection = connection;
            command.Transaction = transaction;

            command.CommandText =
                "Insert into Region (RegionID, RegionDescription) VALUES (100, 'Description')";
            command.ExecuteNonQuery();
            command.CommandText =
                "Insert into Region (RegionID, RegionDescription) VALUES (101, 'Description')";
            command.ExecuteNonQuery();

            // Attempt to commit the transaction.
            transaction.Commit();
            Console.WriteLine("Both records are written to database.");
        }
    }
}

请注意,这里没有显式回滚调用。

因为我已经将SqlTransaction放入一个使用中的块中,所以即使抛出异常,它也始终会被释放。如果执行正常进行,"transaction.Commit()“将提交事务。但是,如果抛出一个异常,而我们没有到达Commit()调用,那么事务将不会被提交,但是它仍然会被释放(在离开using块的作用域时)。我们从文档中了解到,如果事务没有首先提交,或者在没有出现任何错误的情况下被释放,则事务将被回滚。

没有必要在这里捕获任何例外,因为除了这个例外,我们不能做任何有用的事情。我希望在调用链的较高位置处理异常,例如,可能会记录异常并向用户显示友好的错误消息。

总之--文档中的Microsoft示例代码并不总是最好的。

票数 1
EN

Stack Overflow用户

发布于 2020-02-11 17:02:07

事务的回滚将撤消您作为该事务的一部分所做的任何操作。因此,如果启动事务,将几条记录插入到表中,对记录进行更新,而更新失败,回滚也将删除插入的记录。

票数 2
EN

Stack Overflow用户

发布于 2020-02-11 17:13:40

另一种方法是查看system.transactions.transactionscope

它可以在Using内部使用,如果没有完成,就会回滚,而不需要rollback命令。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/60173865

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档