Answer the question
In order to leave comments, you need to log in
How to implement locks in MSSQL database?
Good afternoon. I am writing an application in C# that works with a MSSQL database.
Faced the following problem. Let's admit the user through SELECT loads the data on record in the form for editing. Another user deletes this entry at the same time. Accordingly, the first user at the time of UPDATE will have an error. Or another case - if both users decide to open the same record for editing.
As before, I was not fond of such tasks, I want to know which way to google for the correct implementation of the database locking mechanism in applications.
Answer the question
In order to leave comments, you need to log in
You just have the wrong approach.
You don't need to lock the record, you need to check its version/existence when updating the data.
At your approach, one will block the record and leave for lunch, the work has stopped.
Maybe many will not support me. But my task was to unlock editing, while leaving viewing for the rest. Leaving the version check alone seemed not enough, but I was afraid to implement it through a transaction: it is not known how isolation will behave if it has not been used before.
The implementation was through three additional fields and a couple of procedures. Three is really redundant. Two would be enough. In general, a kind of bike.
Header fields:
And the blocking procedure itself:
ALTER PROCEDURE [dbo].[LockUnLockOrder]
@HeadGUID uniqueidentifier, @UserGUID uniqueidentifier, @Lock bit
AS
BEGIN
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON;
if @HeadGUID is null or @UserGUID is null or @Lock is null
begin
raiserror('Процедура LockUnLockOrder: Неинициализированный параметр',16,1)
return -1
end
if V_ORDER.dbo.CheckEditStatus(@HeadGUID,@UserGUID) = 1
begin
if @Lock = 1
UPDATE [V_ORDER].[dbo].[OrderHeader]
SET isEdit = 1
,BeginEdit = getdate()
,UserEdit = @UserGUID
WHERE GUID = @HeadGUID
else
if @Lock = 0
UPDATE [V_ORDER].[dbo].[OrderHeader]
SET isEdit = 0
,BeginEdit = null
,UserEdit = null
WHERE GUID = @HeadGUID
return 1
end
else raiserror('Невозможно изменить статус заказа',16,1)
end
-- =============================================
-- Author: k1lex
-- Create date: 20160818
-- Description: функция возвращает разрешение редактирования заказа. 1 - можно редактировать. 0 - нельзя
-- =============================================
ALTER FUNCTION [dbo].[CheckEditStatus]
(
-- Add the parameters for the function here
@HeadGUID uniqueidentifier, @UserGUID uniqueidentifier
)
RETURNS bit
AS
BEGIN
DECLARE @bit BIT
IF (
SELECT COUNT(*)
FROM [V_ORDER].[dbo].[OrderHeader] O WITH (NOLOCK)
WHERE O.GUID = @HeadGUID
AND (ISNULL(O.IsReadOnly, 0) = 1 OR (O.userEdit != @UserGUID AND O.IsEdit = 1 AND DATEDIFF(HOUR, BeginEdit, GETDATE()) < 1)
and [Status]=1
)
) = 0
SET @bit = 1
ELSE
SET @bit = 0
RETURN @bit
END
Didn't find what you were looking for?
Ask your questionAsk a Question
731 491 924 answers to any question