【问题标题】:Can a SQL Server database answer during a transaction?SQL Server 数据库可以在事务期间应答吗?
【发布时间】:2009-11-27 18:08:15
【问题描述】:

我使用 .Net 2.0、ADO.NET、一个数据集和数据适配器来管理我的数据,并使用 Microsoft SQL Server 2005 作为数据库管理器。

我有一个应用程序可以生成大量结果 (500K+) 并将它们保存在数据库中。如果一个结果生成失败,我不想保存任何结果。因此,我将所有数据库插入放入一个事务中,如果无法生成结果,该事务将回滚。

但是,在写入所有结果之前,表格会被锁定,这不是我想要的。或者至少我猜它被锁定了,在插入结束之前没有 SELECT 查询响应。

有没有办法让事务在事务处于活动状态时不锁定表?

使用进行如此多插入的事务是否是个好主意?

【问题讨论】:

  • 在处理如此多的行时,您可能需要考虑使用 DataSets 和 DataAdapters 以外的机制。与其他技术相比,它们默认的一次一行的行为可能非常慢。
  • @RickNZ 除了编写我自己的查询和执行 SQLCommand 之外,.Net 2.0 中还有什么可用的?
  • @Wilhelm 你可以试试 SqlBulkCopy,在使用 TableLock 函数时,它的性能比表适配器好得多(尽管仍然不够出色)。
  • eep,我的意思是“选项”,而不是“功能”。

标签: .net sql-server sql-server-2005 ado.net transactions


【解决方案1】:

您可以使用临时登台表。按照你的节奏填写。然后使用一个 SELECT INTO 作为单个事务执行最终移动。大动作完成后,删除临时表。

如果对整体完整性有更严格的限制,您可以引入更多的轻量级表、反映数据流阶段的表、日志/日志表。一些恢复/补偿/清理例程等。

【讨论】:

  • 我看到了这个问题,因为 dba 必须授予用户在数据库中创建表的权限。
【解决方案2】:

您可能需要考虑将事务拆分为更小的批次,每 1k 左右提交一次。

您可以通过在您的选择语句中指定 WITH(NOLOCK) 提示(将其放在表名之后)来越过锁定,但要非常小心,因为它会读取没有已提交(即可能回滚的内容)。还有 WITH(ROWLOCK) 提示可以与您的插入一起使用,这可能会降低锁定选择的机会(如果您尝试访问已插入的行,仍然会发生锁定)通过未提交的事务,但 SQL 不会对整个表进行锁定,因此不太可能)。

您可以找到有关表提示here 的更多信息,请小心使用它们,因为它们会影响性能。希望对您有所帮助。

【讨论】:

  • 我是否必须手动更改数据集中的插入,或者我可以在数据集的某处设置一个标志来为我更改插入?
  • 我不知道有标志,走这条路线时您可能需要修改查询。我建议看看 RocketSurgeon 提出的答案。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-02-02
  • 2010-11-20
  • 1970-01-01
  • 1970-01-01
  • 2023-03-28
相关资源
最近更新 更多