为什么调用提交函数时 SqlTransaction 可能无法提交

本文关键字:提交 调用 函数 为什么 SqlTransaction | 更新日期: 2023-09-27 18:35:38

我遇到了一个问题,即使没有任何查询引发异常,所做的更改也会回滚。 这很奇怪,因为代码在一个环境中工作,但在另一个环境中没有提交更改。

这是处理事务的函数。 当我在提交上放置断点时,我点击了提交,我可以看到数据库中的更改,但是当事务被释放时,更改会回滚。

更新:其他测试表明这不是交易的问题。 如果交易从下面的代码中完全删除,则应用程序的行为方式相同。 连接关闭时,更改将被撤消。

public bool Transaction(List<string> sqlStatements)
{
    using (SqlConnection conn = new SqlConnection(connectionString))
    {
        conn.Open();
        using (SqlTransaction tran = conn.BeginTransaction())
        {
            try
            {
                foreach (string query in sqlStatements)
                {
                    SqlCommand cmd = new SqlCommand(query, conn, tran);
                    cmd.CommandTimeout = 300;
                    cmd.ExecuteNonQuery();
                }
                tran.Commit();
                return true;
            }
            catch (SqlException sqlError)
            {
                tran.Rollback();
                //Log Exception
                return false;
            }
        }
    }
}

为什么调用提交函数时 SqlTransaction 可能无法提交

虽然我很确定,但我最终尝试了您的代码,它按预期工作。我再次重申,该方法对于事务处理来说已经足够好了。一旦事务提交,就无法回滚。

在上述方法中,事务处置与任何回滚无关。我认为,您一直在错误的方向上进行调试。但是,您可以将原始方法粘贴到此处,因为您可能正在执行其他一些数据库操作。

突然,您一直在触发什么样的查询?请注意,DDL 命令是自动提交的,事务不会生效。

当你说你"可以看到数据库中的变化"时,你是如何确定的?如果以下查询返回"已提交"的数据,我希望它们"在数据库中"(例如,在 Sql Server Management Studio 中单步执行提交调用后运行此 tsql):

-- Force the isolation level to "read committed" so we 
-- guarantee we are getting data that has definitely been committed.
-- If the data changes back, it must have been from a separate operation.
set transaction isolation level read committed
begin tran
select * from MyTableWithExpectedChanges;
-- You aren't changing anything so this can be rollback or commit
rollback tran

如果数据确实提交,我将运行 SQL Server 事件探查器会话,看看是什么原因导致数据恢复。听起来好像触发了一些单独的东西来恢复该场景中的数据。

如果数据未提交,则根据其他注释,您存在某种事务计数不匹配。

此问题最终追溯到最近更新为包含事务的触发器。

我们通过从触发器中删除事务来解决此问题。