sql-server - 为什么一个 Java 线程只能取回 SQLServer 中另一个线程插入的数据的一半?
问题描述
在这种特定情况下,我有两个线程:
- 一种是轮询磁盘上特定文件夹中的新文件。它使用文件中的元数据将作业插入数据库(跨多个表)。Autocommit 设置为 false,我只在循环结束时提交(假设一次找到多个文件,每个文件提交一次)。
- 另一个线程不断地轮询要处理的新“作业”。它主要查询一个表,但有几个左连接。该查询
with (updlock, readpast)
仅在主表上使用表提示。
我注意到一些返回的作业缺少一个或多个左连接的值,但只是第一次(它导致失败,然后触发该作业在几秒钟后再次被拾取)。我确定该值实际上不是 null,因为我在每个插入数据的查询之前和之后添加了日志语句。我已确保禁用自动提交,并且只有在所有数据都存在时才提交。
不过,我注意到的一件事似乎是一种模式,即轮询线程在另一个线程完成之前不久就开始了它的查询。它可能是一两个操作落后,或者它可能即将提交。它在第一个线程提交后返回结果(基于我日志中的时间戳)。
我不明白这怎么会发生。我readpast
对主表有一个提示,所以它甚至不应该在查询中返回。但它返回时没有来自连接表的关联数据,它没有任何提示。如果运行需要几秒钟(虽然它通常很快),理论上它应该遇到尚未提交的锁定行,然后跳过它。
这是我用来轮询新工作的查询的一个简单示例。
SELECT distinct
j.id,
p.request_path,
j.revision_id,
j.status,
j.creation_date,
dr.dependent_revision_id
from incoming_jobs j WITH (updlock, readpast)
left join file_paths p on j.revision_id = p.revision_id
left join dependent_revisions dr on j.id = dr.job_id
where j.status in ('WAITING')
and dr.dependent_revision_id is null
order by j.creation_date offset 0 rows fetch next 3 row only
在这种情况下,作业中有一个非空值file_paths
,但无论如何它都会返回空值。incoming_jobs
该值在另一个线程将作业插入表后立即插入。
解决方案
推荐阅读
- javascript - JavaScript 中的比较运算符
- c++ - 我收到一段代码的警告,但是 bjarne stroustrup 的 c++ 书说它应该是一个错误。这里有什么?
- mysql - 我正在使用 mysqlcommand 在 db 中输入数据,但某些变量已识别,其他变量未识别,请检查代码
- powershell - Test-Path 是否接受相对路径?
- c++ - C++ 模板类仅由 uint8_t 类型崩溃
- javascript - 如何获取由 querySelectorAll() 方法 (javascript) 生成的 DOM 数组的每个元素的索引?
- msys2 - 在 MSYS2 MINGW32 shell 中运行软件构建
- amazon-web-services - 如何在 AWS Lambda C# 中获取环境变量
- sql - 在雪花中选择常量和*?
- python - 发布者/消费者用于在 eth0 int 中捕获 AMQP 包,但是当我运行此代码时,我只能在环回接口中捕获数据包