【问题标题】:DbDataReader inner workingDbDataReader 内部工作
【发布时间】:2017-12-07 02:10:39
【问题描述】:

我们拥有由 SQL Server 和 .NET 应用程序组成的高负载系统。 我们正在使用DbDataReader 从 SQL 中检索数据并将其保存到 JSON 中以通过网络发送。我们的系统对所有插入或修改的记录使用时间戳,以便仅通过网络发送更新的数据(每个表都有提取日期时间列,该列在插入或修改记录时更新)。

在某些情况下,我们看到数据库中的一些记录会在我们持久化 JSON 的同时更新。对于这些记录,我们不会在 JSON 中看到它们,但在我们手动检查时会在 DB 中显示正确。更奇怪的是,具有相同日期时间戳(最多相同毫秒)的其他记录存在于 JSON 中。所以问题是,下次我们从数据库中检索数据时,我们只会获得超过特定日期时间的记录,这会导致丢失在写入 JSON 的同时修改的几条记录。

我最初的想法是写 JSON 时记录没有被修改可能是时间问题。但是你如何处理这种情况呢?

所以我的问题是,DbDataReader 将只返回执行 DbCommand.ExecuteReader() 时存在的记录,还是返回之后在数据库中修改的记录?

【问题讨论】:

  • 除了ExecuteReader,您还在使用reader.Read()
  • 查询运行的隔离级别是多少?您是否启用了 READ COMMITTED SNAPSHOT 数据库选项?
  • 读取数据库时会包含数据库中的记录。当它执行必要的 SQL 查询时,它将获取数据库中的数据,而不是之后插入的任何数据。我错过了什么吗?我不知道您指的是什么“时间戳”,但是具有相同的“时间戳(最多毫秒”)并不能保证记录是同时插入的,即使该时间戳是由插入触发器生成的。
  • 读取 SQL 服务器时,您必须使用 Order By,因为数据不是按顺序或时间存储的。 SQL Server 进行并行处理以提高事务的速度。它还进行锁定以防止一个用户在另一个用户修改数据位置时读取数据。因此,可能在执行读取查询时,另一个用户更改了数据,结果将显示更改。
  • @DavidBrowne-Microsoft:我认为我们没有启用该选项。它有什么作用?

标签: c# sql-server database ado.net


【解决方案1】:

问题是下次我们从数据库中检索数据时,我们只能获取超过特定日期时间的记录,这会导致丢失一对记录

您似乎正试图从 SQL Server 表中提取不相交的行子集。在这种情况下,没有必要深入了解事务隔离级别的详细信息。

底线是,除非您使用持续至少几毫秒的表锁定,否则您不能使用日期时间列从 SQL Server 表中提取不相交的增量。您会在提交时看到行,而不是在写入时看到行。因此,即使时钟分辨率是无限的,事务也可以按照与读取时钟和写入行不同的顺序提交。

可以为此使用 rowversion 列,因为 SQL Server 会为每个事务增加值。

或者您可以构建您的提取逻辑以期望重叠的行。

或使用事务复制、更改数据捕获或更改跟踪。

【讨论】:

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