我在一个小系统上工作,它接收来自多个来源的大量数据(数以百计的数据)。取决于几个因素,我可以得到从几行到几千行的任何信息(实际上,最小的消息包含单行,而最大的消息最多包含5000行,但是如果应该加载更多的数据,那么我可以在几个批中获得这些数据)。目前,很少有相同的服务处理数据。每个服务将数据加载到五个暂存表中的一个,并执行正确的过程--每个暂存表都有与其相关联的不同过程,但它始终归结为将唯一标识符(例如UUID)更改为正确的数据库标识符,将数据插入目标表并从暂存表中删除数据。所有程序均有以下表格:
INSERT INTO TARGET (A, B, C)
SELECT T1.ID, B, C FROM STAGING_TABLE
JOIN T1 ON A = T1.ID
DELETE FROM STAGING_TABLE所有服务都可以并行地处理单个暂存(和目标)表。目前,这是使用快照隔离完成的,但很明显,由于某种原因,我们正在丢失数据,这是非常痛苦的。我的意思是,有些消息被服务正确地处理,但是来自它们的所有信息都丢失了--我们看不到数据库中的记录。我不能证明快照隔离是负责任的,但是在引入快照隔离之后,这种事件就开始发生了--然后引入了并行加载服务数据之后就引入了快照隔离。数据库目前离我的主要专业领域很远,我不知道为什么会发生这种情况,但是快照隔离似乎是主要的罪魁祸首。
我的问题是:支持这种情况的最低隔离级别是什么?有更好的方法吗?我不完全知道以前使用了什么事务隔离级别(当数据被单个服务加载时),但我们从未观察到数据丢失。我尝试(盲目地)使用“可序列化”和“可重复读取”,但是“序列化”会导致由于死锁而丢弃消息,而“可重复读取”似乎做了正确的事情(没有数据丢失),也会将性能降低到串行写入的水平。
编辑:是否可以使用快照隔离加载数据,插入临时表(或表变量),然后切换到非常允许的隔离级别,将数据从临时表插入到目标表,恢复到快照并从暂存表中删除数据?如果我看得对:
https://learn.microsoft.com/en-us/previous-versions/sql/sql-server-2005/ms173763(v=sql.90)
这应该是可能的,但我还不明白在讨论的案例中是否会有任何影响-目标表不会被读取,只在这个场景中被写入,而且我认为这意味着写不会比快照隔离下的“更并行”。但也许我错了?
请注意,我们不能等待,例如,将数据从多个源加载到单个暂存表中,然后将其移动到目标表中。我们的目标不是实时的,但我们需要尽快插入数据。
发布于 2021-12-06 15:02:36
我很久以前就发现问题出在哪里,但直到现在我才发现我还没有给出这个问题的答案。问题是:
DELETE FROM STAGING_TABLE
OUTPUT DELETED.*
INTO ...数据丢失的原因是微不足道的--我们在临时表中插入一些行,然后删除整个表的内容。随着数据不断加载到暂存表中,在insert和delete语句之间添加了一些记录--这些
https://dba.stackexchange.com/questions/242372
复制相似问题