如何在 ETL 管道中正确截断临时表?

emz*_*ero 5 sql-server etl locking staging-table azure-sql-database

我们有一个 ETL 管道,它为上传到存储帐户 (Azure) 的每个 CSV 运行。它在 CSV 上运行一些转换并将输出写入另一个位置,也作为 CSV,并调用数据库 (SQL Azure) 上的存储过程,该过程将生成的 CSV 摄取 (BULK INSERT) 到一个临时表中。

该管道可以同时执行,因为多个资源可以将文件上传到存储。因此,临时表经常插入数据。

然后,我们有一个计划的 SQL 作业(弹性作业),它触发一个 SP,将数据从临时表移动到最终表中。此时,我们希望截断/清空临时表,以便我们不会在下次执行作业时重新插入它们。

问题是,我们无法确定在从暂存表加载到最终表和 truncate 命令之间,没有任何新数据写入暂存表可以在没有先插入最终表的情况下被截断。

有没有办法在我们将数据复制到最终表时锁定临时表,以便尝试写入它的 SP(从 ETL 管道调用)只会等到锁定被释放?这是否可以通过使用事务或一些手动锁定命令来实现?

如果没有,处理这个问题的最佳方法是什么?

Pio*_*otr 1

我会建议使用两个相同的临时表的解决方案。我们将它们命名为 StageLoading 和 StageProcessing。
加载过程将具有以下步骤:
1. 开始时两个表都是空的。
2.我们将一些数据加载到StageLoading表中(我假设每次加载都是一个事务)。
3. 当 Elastic 作业启动时,它将执行以下操作:
- ALTER TABLE SWITCH 将所有数据从 StageLoading 移至 StageProcessing。它将使 StageLoading 清空并为下一次加载做好准备。这是一个元数据操作,因此需要几毫秒并且完全阻塞,因此将在加载之间完成。
- 将数据从 StageProcessing 加载到最终表。
- 截断表阶段处理。
4. 现在我们已经准备好进行下一个 Elastic 工作了。

如果我们尝试在 StageProcessing 不为空时执行 SWITCH,则 ALTER 将失败,这意味着上次加载过程失败。