c# - 事务不在 C# 中回滚

标签 c# sql-server transactions rollback

private void btnConfigure_Click(object sender, EventArgs e)
{
    try
    {
        dbConfigure dc = new dbConfigure();
        SqlTransaction tr = conn.BeginTransaction();
        cmd.Transaction = tr;
        if (dc.configuration(cmd, ps.tableNames))
            tr.Commit();
        else
        {
            tr.Rollback();
            mesg.show("Transaction is Rolled back");
        }
    }
    catch (Exception ex)
    {
        mesg.show(ex.Message);
    }
}

如果我在 configuration 的任何地方遇到问题方法然后它返回 false 我可以看到消息 Transaction is Rolled Back .但实际上事务并没有完全回滚,尽管回滚是非常不希望的,但此函数对数据库结构所做的一些更改仍然存在。我的问题是事务回滚发生故障的可能性有多大?

除了共享(上述)方法外,我的项目中没有其他任何事务

小细节

我正在调用一个非常冗长/复杂的函数 configuration我类的dbConfigure .它对数据库结构进行了一些必要的更改。例如它

  1. 删除外键
  2. 删除主键
  3. 删除自增字段

    它会在删除之前保存这些键并以所需的顺序/位置重新创建

conn是一个 SqlConnection已经打开,除此之外我没有使用任何连接

cmdconn.CreateCommand()除了这个,我没有在任何地方使用任何命令

在这整个过程中我从未关闭连接,但是 SqlDataReader 在 configuration 中关闭了在他们工作时发挥作用。

最佳答案

Changes to database structure are not transactional, so you cannot rollback creation of a new table, for example

废话。大多数 DDL 是事务性的并且可以回滚。只有涉及与非事务性组件交互的更改(如文件系统,例如将新文件添加到数据库)不能回滚。如果在事件事务中调用,任何非事务性 DDL 也会非常明确地引发异常。

添加和修改表是非常明确的事务性的,可以很容易地用一个例子来说明:

begin transaction;
create table foo (a int);
select * from sys.tables where object_id = object_id('foo');
rollback;
select * from sys.tables where object_id = object_id('foo');

因此问题在于OP缺少代码,没有发布的部分。

作为一般性评论,应尽可能使用 System.Transactions(考虑到 the default constructor is broken)。如果使用 SqlConnection.BeginTransaction,最好还是依赖 IDisposable:

using (SqlTransaction trn = conn.BeginTransaction())
{
   ...
   trn.Commit ();
}

System.Transactions 应该受到青睐,因为它们不依赖于代码规则,事务范围内的任何代码 SqlClient 都会自动注册。

顺便说一句,配置函数在错误时引发错误,而不是返回 false。

以及潜在的实际问题:如何处理不可能在单个事务中注册的冗长、复杂的迁移(例如,它可能会生成太多日志)。答案是唯一可行的选择是在迁移开始时进行数据库备份,如果迁移失败则从该备份中恢复。为每个迁移操作提供手动、经过测试和可靠的补偿操作以撤消迁移的替代方法非常困难、容易出错,而且最终没有必要,因为从备份中恢复非常简单且可证明正确的。

关于c# - 事务不在 C# 中回滚,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13396980/

相关文章:

mysql - SQL 数字格式

sql-server - 无序读取列会返回不正确的值(SQL Server ODBC 驱动程序)

asp.net - 基于权限的动态Web表单

mysql - 使用 myisam 将激活 key 存储在单独的表中

.net - 如何在.NET 中对多个 SqlConnection 使用单个 SqlTransaction?

c# - 如何在 winform 中使用自定义纸张尺寸进行打印

C# 列表框绑定(bind)到实体 "Entity Framework"

php - 使用 CURL 发布方法的 Google 翻译 API

c# - 使用局部作用域变量别名

c# - Unity 可以一直不抛出 SynchronizationLockException 吗?