如何最小化锁定同时保持数据库相关操作是原子的
How to minimize locking yet maintaining the database related operation is atomic
我有一个关于如何最大限度地减少数据库锁定同时又保证操作是原子操作的一般性问题。我的案例具体涉及 C# / SQL 服务器,但这可能是一个语言不可知的问题。
我们必须定期将销售收入写入文件并通过 FTP 将其发送到另一台服务器。这是我们当前的流程:
- 从 Sales Table 中获取上一小时未处理的总销售额
- 将总销售额/收入/杂项信息写入文件
- 开始数据库事务
- 更新销售 Table 表示销售已处理
- 发送文件到FTP
- 提交交易
问题是,我们向 FTP 服务器发送了大量文件,这个过程需要很长时间。这导致了一些锁定问题,我们的客户无法注册或修改销售。但是,如果 FTP 传输或数据库更新因任何原因失败,我们需要回滚数据库操作并删除任何以前发送的文件。
推荐的方法是什么来保证操作是原子的同时最小化锁定?
您可以为销售的状态字段添加更多含义 table:
- 未处理
- 处理中
- 已处理
这样您就不必在通过 FTP 发送文件所需的整个持续时间内锁定行(和 MS SQL 服务器中的页面)。您只需在选择相关记录时锁定它们,然后将状态更新为"Processing",最后释放锁定。
在 FTP 作业完成后,您将相关记录更新为 "Processed"。
您还应该制定一个计划流程来检查 FTP 作业是否失败。属于失败 FTP 个进程的记录状态应再次更新为 "Not Processed"。
编辑:您可以在下面找到 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
我有一个关于如何最大限度地减少数据库锁定同时又保证操作是原子操作的一般性问题。我的案例具体涉及 C# / SQL 服务器,但这可能是一个语言不可知的问题。
我们必须定期将销售收入写入文件并通过 FTP 将其发送到另一台服务器。这是我们当前的流程:
- 从 Sales Table 中获取上一小时未处理的总销售额
- 将总销售额/收入/杂项信息写入文件
- 开始数据库事务
- 更新销售 Table 表示销售已处理
- 发送文件到FTP
- 提交交易
问题是,我们向 FTP 服务器发送了大量文件,这个过程需要很长时间。这导致了一些锁定问题,我们的客户无法注册或修改销售。但是,如果 FTP 传输或数据库更新因任何原因失败,我们需要回滚数据库操作并删除任何以前发送的文件。
推荐的方法是什么来保证操作是原子的同时最小化锁定?
您可以为销售的状态字段添加更多含义 table:
- 未处理
- 处理中
- 已处理
这样您就不必在通过 FTP 发送文件所需的整个持续时间内锁定行(和 MS SQL 服务器中的页面)。您只需在选择相关记录时锁定它们,然后将状态更新为"Processing",最后释放锁定。
在 FTP 作业完成后,您将相关记录更新为 "Processed"。
您还应该制定一个计划流程来检查 FTP 作业是否失败。属于失败 FTP 个进程的记录状态应再次更新为 "Not Processed"。
编辑:您可以在下面找到 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