【问题标题】:Using transactions when inserting records in the Database with C#使用 C# 在数据库中插入记录时使用事务
【发布时间】:2011-08-11 16:21:13
【问题描述】:

我从未使用过 SQL 事务,就我而言,我知道我真的必须使用它们。我的应用程序的功能之一是将 Excel 文件转换为数据库。

所以我从 Excel 中获取值,使用参数构建一个字符串数组(发送到 SP),其中一些值我将直接插入到主表中,而其他值我将插入到辅助表中,然后我会得到 id,谁将代替主表中的这些值。我的意思是我有外键,这就是我这样做的原因。

所以我认为我做得很完美,但没有交易。但是,如果我在表中插入值时出现任何问题,我将不得不进行回滚。

所以在这个过程中,我使用了 5 个存储过程,每个表一个。这些 SP 并不是这个过程所独有的。它们将在 App 中用于插入记录。

但我需要有关在何处使用事务的帮助。我应该在 C#(应用程序端)还是在 SQL Server(服务器端)中执行此操作?

现在我正在使用 C# 中的 SqlTransaction 对象,它以某种方式工作,因为如果我执行回滚,他真的会取消所有插入,但我在事务中使用的 ID 不再可用。只有当我删除所有表并重新创建它们时,这些 ID 才能再次可用。

所以我认为我没有很好地使用交易,这就是为什么我需要帮助,以了解如何以及在哪里更好地使用交易。

【问题讨论】:

  • [只有当我删除所有表并再次创建它们时,这些 ID 才会再次可用。] 完全正确,这就是 IDENTITY 列的工作方式。如果你问这个,你需要去读一些书

标签: c# sql sql-server tsql transactions


【解决方案1】:

我认为您在使用事务的方式上走在正确的轨道上,问题是 IDENTITY 列的种子没有回滚。

我猜你正在使用 MS SQL Server?要在不重新创建表的情况下重置 IDENTITY 列,可以使用 DBCC CHECKIDENT。

DBCC CHECKIDENT (table_name, RESEED, 99);

这将重置种子,以便分配的下一个标识值是 100。当然,您必须在 BEGIN TRANSACTION 之前记录表的最高标识值。

我只会在只有一个写入器进程的情况下使用它。在多写者的情况下,除非你先做一些严重的表锁定,否则事情很可能会进展顺利。在多个作者的情况下,我认为您最好编写其余的代码,这样标识列值中的“漏洞”是可以接受的。

【讨论】:

    【解决方案2】:

    如果您没有将身份列用于其他目的,并且不绝对要求它是连续的,请尝试习惯它会有“缺失”值的想法。它们并没有真正丢失,因为它们只是提供了一种为每条记录提供廉价唯一密钥的方法。删除记录时也会出现空白,因此也不应将 Identity 列作为记录计数器。

    当我们查看表格时,看到序列号对我们的大脑来说是件好事,但代价是您自己和数据库引擎的额外工作。我花了几个月的时间才接受它。

    该值不被重用的原因是当该列用作外键时有助于提供数据库完整性。

    【讨论】:

      猜你喜欢
      • 2015-01-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-08-04
      相关资源
      最近更新 更多