sql-server - 锁定行以进行读取和更新 - 一次只有一个进程应该更新一行
问题描述
我被要求检查我需要帮助的生产问题。我试图了解 SQL Server 中可用的隔离级别和不同的锁。
我有一个JOB_STATUS
有列的表job_name (string, primary key), job_status (string), is_job_locked (string)
样本数据如下:
工作名称 | 工作现状 | is_job_locked |
---|---|---|
作业_A | 不活跃 | ñ |
工作_B | 跑步 | ñ |
工作_C | 成功 | ñ |
作业_D | 跑步 | ñ |
工作_E | 不活跃 | ñ |
多个进程可以通过调用存储过程并传递job_name
as 输入参数来同时更新表。如果两个不同的行同时被不同的进程更新,那很好。
但是,两个进程不应同时更新同一行。
更新查询示例如下:
update JOB_STATUS set is_job_locked='Y' where job_name='JOB_A' and is_job_locked='N';
在这里,如果两个进程正在更新同一行,那么一个进程应该等待另一个进程完成。此外,如果is_job_locked
列值被一个进程更改为Y
,则另一个进程不应再次更新它(如果锁定正确,我的更新语句应该处理)。
那么我该如何进行这种行级锁定并确保更新查询在使用存储过程进行更新之前从行中读取最新数据。
另外,想根据条件获取更新查询是否更新了行或没有更新的返回值,以便我可以在进一步的应用程序流程中使用该值。
解决方案
RE:“如果两个进程正在更新同一行,那么一个进程应该等待另一个进程完成。”
这就是锁定在 SQL Server 中的工作方式。UPDATE 在行上采用排他锁——其中“排他”表示该词的英文含义:UPDATE 进程在运行时已排除(锁定)所有其他进程。其他进程现在等待 UPDATE 完成。这包括事务隔离级别 READ COMMITTED 及以上的 READ 进程。当 UPDATE 锁被释放时,下一条语句就可以访问该值。
如果您正在寻找的是 2 个进程不能同时更改单个表中的同一行,那么 SQL Server 会立即为您执行此操作,您无需添加自己的“is_job_locked”列。
但是,通常使用 is_job_locked 列来控制对单个表之外的访问。例如,它可用于防止第二个进程启动已在运行的作业。进程 A 将标记 is_job_locked,然后启动作业。进程 B 将在尝试开始作业之前检查标志。
推荐阅读
- haskell - 将 GADT 与 DataKinds 一起用于函数中的类型级数据构造函数约束
- connection - 德州仪器 DCA1000 雷达问题
- angular - 自定义 ErrorHandler 提供程序为响应异步事件而打开的对话框未关闭
- sql - Presto - 使用数组的每个索引将 2 个数组转换为单独的映射实体
- angular - AngularFire2 Microsoft Auth 提供 POST https://www.googleapis.com/identitytoolkit/v3/relyingparty/verifyAssertion 400
- c# - 查询一对一关系
- r - 对于在数据帧中创建新变量的循环,在 R 中运行多个数据帧
- mysql - 如何使用 docker-compose 将 csv 加载到 mysql 中?
- android - 应用打开时接收 FCM 通知的问题
- postgresql - 授予服务帐户的权限,但在将 csv 从 GCP 存储桶导入 GCP postgres db 时,Bash 操作员失败