如何在最小化锁定的同时维护与数据库相关的操作是原子性的

本文关键字:数据库 操作 原子性 最小化 锁定 维护 | 更新日期: 2023-09-27 18:09:07

我有一个关于如何最小化数据库锁定同时保证操作是原子性的一般性问题。我的案例特别涉及c#/SQL Server,但这可能是一个语言不可知论问题。

我们必须定期将销售收入写入一个文件,并通过FTP将其发送到另一个服务器。下面是我们当前的流程:

  • 从销售表中获取最近一小时未处理的总销售额
  • 将总销售额/收益/杂项信息写入文件
  • 开始数据库事务
  • 更新销售表,显示已处理的销售
  • 发送文件到FTP
  • <
  • 提交事务/gh>

问题是,我们发送大量的文件到FTP服务器,这个过程需要相当长的时间。这导致了一些锁定问题,我们的客户无法注册或修改销售。但是,如果FTP传输或数据库更新由于任何原因失败,我们需要回滚db操作并删除任何先前发送的文件。

推荐的方法是什么来保证操作是原子的同时最小化锁?

如何在最小化锁定的同时维护与数据库相关的操作是原子性的

您可以为Sales表的状态字段添加更多含义:

  • 不处理
  • 处理

这样,您就不必在通过FTP发送文件所需的整个持续时间内锁定行(和MS SQL Server中的页面)。您只需在选择相关记录时锁定它们,然后将状态更新为"正在处理",最后释放锁定。

FTP作业完成后,将相关记录更新为"Processed"。

您还应该开发一个计划进程来检查FTP作业是否失败。属于失败FTP进程的记录状态应重新更新为"未处理"

编辑:您可以在

下面找到SQL脚本
begin tran
declare @toBeProcessed table(saleid int);
insert into @tobeProcessed
select saleid
from Sales (rowlock) 
where status = 'NotProcessed'
update Sales
set status = 'Processing'
where saleid in (select saleid from @toBeProcessed)
commit
select * from @toBeProcessed