Quiero actualizar un solo registro en una tabla para reflejar que una sesión de cliente determinada ha adquirido el registro (y ahora lo posee para más actualizaciones) dentro de un entorno de sesiones múltiples. Tengo esto hasta ahora:Actualización de registro atómico exclusivo de SQL
create procedure AcquireRow(
@itemNo int, -- Item ID to acquire
@sessNo int, -- Session ID
@res char(1) out) -- Result
as
begin
-- Attempt to acquire the row
update Items
set
State = 'A', -- 'A'=Acquired
SessionID = @sessNo
where ItemID = @itemNo
and State = 'N'; -- 'N'=Not acquired
-- Verify that the session actually acquired the row
set @res = 'T'; -- 'T'=Success
if @@rowcount = 0
set @res = 'F'; -- 'F'=Failure
end;
La variable de salida se establece en @state
'T'
si el procedimiento ha adquirido con éxito la fila, de lo contrario se configura en 'F'
para indicar el fracaso.
Mi pregunta: ¿Es esta garantizado para trabajar de forma atómica, por lo que sólo adquiere una sesión con éxito (actualizaciones) la fila si varias sesiones llaman AcquireRow()
al mismo tiempo? ¿O hay una mejor manera de hacer esto? ¿Necesito un rowlock
explícito?
modificada:
Basado en la respuesta de Remus, me reorganizar el código así:
set @res = 'F';
update ...;
if @@rowcount > 0
set @res = 'T';
Uso de una cláusula de output
o asignar de ItemID
la fila resultante a una variable dentro de la update
también sería prudente.
Una pregunta muy similar ha sido formulada en SO, pero no puedo encontrarla ... –
Esta es similar pero no la que tenía en mente: http://stackoverflow.com/questions/574549/ efficient-transaction-record-locking –