我们有一个ETL管道,为上传到存储帐户(Azure)中的每个CSV运行。它在CSV上运行一些转换,并将输出也作为CSV写入另一个位置,并在数据库(SQL Azure)上调用存储过程,该存储过程将生成的CSV吸收(批量插入)到登台表中。
该管道可以并发执行,因为多个资源可以将文件上传到存储中。因此,登台表会经常插入数据。
然后,我们有一个计划的SQL作业(Elastic Job),该作业触发一个SP,该SP将数据从登台表移到最终表中。
此时,我们希望截断/清空登台表,以免在下一次执行作业时不重新插入它们。
问题是,我们不能确定在从临时表到最终表的加载与truncate命令之间,没有任何新数据写入到临时表中而没有先插入到最终表中就可能被截断。
当我们将数据复制到最终表中时,是否有一种方法可以锁定登台表,以使试图写入该表的SP(从ETL管道调用)将只等到该锁被释放为止?通过使用事务或某些手动锁定命令可以实现此目的吗?
如果没有,处理此问题的最佳方法是什么?
最佳答案
我将提出两个相同的登台表的解决方案。让我们将它们命名为StageLoading和StageProcessing。
加载过程将包括以下步骤:
1.开始时,两个表都是空的。
2.我们将一些数据加载到StageLoading表中(我假设每次加载都是一个事务)。
3.当弹性作业开始时,它将执行以下操作:
-ALTER TABLE SWITCH将所有数据从StageLoading移到StageProcessing。这将使StageLoading为空,并为下一次加载做好准备。这是一个元数据操作,因此需要花费几毫秒的时间,并且会完全阻塞,因此将在加载之间完成。
-将数据从StageProcessing加载到最终表。
-截断表StageProcessing。
4.现在我们准备好进行下一个弹性工作。
如果我们在StageProcessing不为空时尝试执行SWITCH操作,则ALTER将会失败,这意味着最后一次加载过程失败。