我在同一JDBC连接上并行运行~22个MERGE命令。我在所有并行执行完成后提交事务。我已打开显式交易。以下是我正在使用的合并命令:
MERGE INTO _1 AS A USING ( select $1:Id::VARCHAR as Id, $1:modifiedUtc::NUMBER as MODIFIEDUTC, $1:VersionId::NUMBER as VersionId, $1 as DATA FROM '@EXTERNAL_AWS_STAGE/group1/' (FILE_FORMAT => JSON_FORMAT) ) AS B ON A.Id = B.Id WHEN MATCHED AND A.VersionId < B.VersionId THEN UPDATE SET A.VersionId = B.VersionId, A.MODIFIEDUTC = B.MODIFIEDUTC, A.DATA = B.DATA WHEN NOT MATCHED THEN INSERT (Id, MODIFIEDUTC, VersionId, DATA) VALUES (B.Id, B.MODIFIEDUTC, B.VersionId, B.DATA);
MERGE INTO _2 AS A USING ( select $1:Id::VARCHAR as Id, $1:modifiedUtc::NUMBER as MODIFIEDUTC, $1:VersionId::NUMBER as VersionId, $1 as DATA FROM '@EXTERNAL_AWS_STAGE/group2/' (FILE_FORMAT => JSON_FORMAT) ) AS B ON A.Id = B.Id WHEN MATCHED AND A.VersionId < B.VersionId THEN UPDATE SET A.VersionId = B.VersionId, A.MODIFIEDUTC = B.MODIFIEDUTC, A.DATA = B.DATA WHEN NOT MATCHED THEN INSERT (Id, MODIFIEDUTC, VersionId, DATA) VALUES (B.Id, B.MODIFIEDUTC, B.VersionId, B.DATA);
使用三个相同的表,问题是某些表没有更新,而其他表则更新。这并不是说特定表没有更新。有时,说表 _1 正在更新,有时没有。我验证了 executeUpdate(query( 方法为所有 MERGE 命令返回 1,表明所有表都更新或插入了一行,但从 _1 中选择 * 为其中一些返回 0 行。代码库提交或回滚事务,最终关闭连接。
当我尝试通过雪花工作表运行相同的 MERGE 命令时,我可以看到所有表中的数据都已更新。
任何指针都会非常有帮助。
一些重要的观察结果:
- 由于我们必须在事务边界内处理更新,因此我们调用 Connection.setAutoCommit(false(。如果未启用此功能,则不会观察到上述问题。
- 我们正在将 20 个查询分批发送到 Snowflake 执行。所有 20 个查询都使用相同的数据库连接同时触发。每批 20 个 MERGE 命令后跟 2 秒的暂停。
- 如果我们尝试按顺序执行 MERGE 命令,则不会观察到问题。即使在表上有几个活动锁之后,提交也会成功,并且表中的数据也会更新。
- 对于空的数据表,即使是雪花历史记录也说 MERGE 命令成功完成,每个 MERGE 命令的行计数为 1。
- SHOW TRANSACTIONS 命令仅在事务处于活动状态之前显示活动事务。成功提交后,此命令不显示任何活动事务。
- SHOW LOCKS 命令显示可变数量的锁,范围从 1 到超过所涉及的表数。
- 如果我们检查 SHOW LOCKS 命令的结果集中返回的查询 ID 的历史记录,我们会发现查询已成功完成。
请提供可能有助于进一步确定问题的任何指示。
您是否正在使用最新的 Snowflake JDBC 连接器并按如下方式显式设置多语句选项? https://docs.snowflake.net/manuals/user-guide/jdbc-using.html#multi-statement-jdbc