我正在进行批量更新,按顺序处理记录(用户 1、用户 2 等)。每条记录都有多个与其关联的更新查询。如果单个记录(在本例中为用户)存在数据问题,我需要跳过。理想情况下,我想并行处理它们,但还没有达到那个水平(有很多挑战)。
是否可以这样做:
- 有一个交易。
- 如果出现故障,与该记录关联的语句将回滚,而不影响其他记录。
- 犯罪。
例如,我的 CSV 文件中有 4 个用户。如果 3 个是好的,1 个是坏的,则 3 个应该原子地提交(或中止);1 应该因错误而被跳过。
观察到的:
do everything for user 1;
do everything for user 2;
--> if there is failure, it rolls back the *entire* transaction
do everything for user 3;
事实上,任何错误级别 >= 16 都会回滚整个事务。
预期的:
do everything for user 1;
do everything for user 2;
--> if there is failure, roll back this *block* only
do everything for user 3;
do everything for user 4;
这是任何编程语言的正常try-catch
要求;但是,无法看到 SQL Server 等效项(涉及事务)。我读过有关检查点的内容,但不确定这是否是一个值得考虑的选项。
不可能提交事务的某些部分并回滚其他部分。这将违背交易的要点:交易中的所有内容作为一个单元成功或失败。换句话说,事务是原子的。
听起来很像您不希望整个过程中发生一笔交易。这意味着要么所有记录都已成功处理,要么没有。任何错误都会确保持久数据库返回到发生任何更改之前的状态。
根据您的描述,您似乎应该为每个用户启动一个新事务。
执行该用户所需的所有更改,然后根据是否遇到任何致命错误情况提交或回滚。您可能希望针对死锁等暂时性(可解决的)错误构建有限次数的重试。或者将它们记录在某处以便稍后重试。
这种安排将导致您想要的结果:没有错误的用户是成功的,有错误的用户将撤消所有更改。
理想情况下,您还可以编写例程,以便在发生灾难时从故障点重新启动。这样可以避免在发生故障时重新处理已成功处理到数据库中的用户数据。
有关详尽的指南,请参阅Erland Sommarskog 撰写的SQL Server 中的错误和事务处理。
对每个用户运行事务的更改可能会对性能产生影响。您是否注意到它取决于每个用户完成了多少其他工作以及其他因素。
请记住,如果您没有使用显式事务,则每个语句都将在其自己的自动提交事务中运行。
例如,如果这在您的特定情况下是一个重要因素,您可以考虑使用延迟持久性、改善系统日志的整体性或在多个线程上运行该进程。
您不必自己编写所有内容。有许多工具和技术可以从 CSV 输入中读取数据,并将这些更改通过管道传输到数据库中(也许是并行的)。例如,SSIS、Azure 数据工厂和 Synapse 管道。
请根据需要随意提出单独的后续问题。