在 SQL Server 2000 中,取得最近一次的 ID(通常指自增 ID,即 IDENTITY 列)并锁定该行,核心是结合自增 ID 获取函数与事务、锁机制,确保数据一致性,避免并发冲突,具体方法如下(分 2 种常用场景,适配 SQL2000 版本特性):
一、场景 1:刚执行 INSERT 操作,获取本次插入的 ID 并锁定该行
适合插入数据后,立即需要操作该条新数据(如更新、读取),需锁定防止其他会话修改 / 删除。
核心逻辑:用SCOPE_IDENTITY()获取当前会话、当前作用域内最后插入的自增 ID(优先推荐,避免跨会话干扰),配合事务 + 行级锁锁定该行。
示例代码(假设表名table1,自增 ID 列id):
BEGIN TRANSACTION -- 开启事务,确保锁的有效性
-- 1. 插入数据(示例)
INSERT INTO table1 (col1, col2) VALUES ('value1', 'value2')
-- 2. 获取本次插入的最近ID
DECLARE @lastID INT
SET @lastID = SCOPE_IDENTITY()
-- 3. 锁定该行(行级锁,用SELECT ... FOR UPDATE,SQL2000支持)
SELECT * FROM table1 WHERE id = @lastID FOR UPDATE
-- (后续可执行对该条数据的操作,如更新、删除等)
COMMIT TRANSACTION -- 提交事务,释放锁;若出错用ROLLBACK TRANSACTION回滚
关键说明:SCOPE_IDENTITY()仅返回当前会话、当前存储过程 / 语句块中插入的 ID,避免IDENT_CURRENT('table1')(跨会话)、@@IDENTITY(跨作用域)的干扰,更安全。
锁机制:FOR UPDATE会对符合条件的行加行级排他锁,其他会话无法对该行执行更新、删除操作,直至当前事务提交 / 回滚,实现 "锁定该行" 的需求。
二、场景 2:未执行插入,获取表中已存在的 "最近一次 ID"(最大 ID)并锁定该行
适合从现有数据中取最大 ID 对应的行,锁定后进行操作,避免并发时 ID 被修改或行被删除。
核心逻辑:用MAX(id)获取最大 ID(即最近一次插入的 ID),配合事务 + 行级锁,确保获取 ID 和锁定行的原子性。
示例代码:
BEGIN TRANSACTION
-- 1. 获取表中最近一次的ID(最大ID),并锁定该行
DECLARE @lastID INT
SELECT @lastID = MAX(id) FROM table1 WITH (UPDLOCK, HOLDLOCK)
-- 2. 再次锁定该行(双重保障,确保行不被修改)
SELECT * FROM table1 WHERE id = @lastID FOR UPDATE
-- (后续操作该条数据)
COMMIT TRANSACTION
关键说明:
WITH (UPDLOCK, HOLDLOCK):UPDLOCK 加更新锁,HOLDLOCK 保持锁直至事务结束,避免获取 ID 后,该行被其他会话修改导致 ID 失效。
若表中无数据,MAX(id)会返回 NULL,需提前判断(如IF @lastID IS NOT NULL),避免报错。
重要注意事项(SQL2000 版本限制)
仅支持IDENTITY自增列的 ID 获取,若 ID 不是自增(如手动赋值),需用MAX(id)获取最近 ID,无其他专属函数。
锁机制依赖事务,必须在BEGIN TRANSACTION和COMMIT/ROLLBACK之间执行锁定操作,否则锁会立即释放。
避免使用NOLOCK(脏读),确保锁定的行数据是最新、未被修改的。