Please start any new threads on our new site at https://forums.sqlteam.com. We've got lots of great SQL Server experts to answer whatever question you can come up with.

 All Forums
 SQL Server 2000 Forums
 SQL Server Development (2000)
 Something like thread locking...

Author  Topic 

adweigert
Starting Member

22 Posts

Posted - 2003-09-30 : 19:34:18
I need a way to ensure at the database level that a certain operation is only happening at any given time for a particular process. Table locking, right?

Basically I have a table of users and a table for user authorizations...

On login, I need to check the authorizations table to see if there is a current active authorization. If there is I need to de-activate it and insert a new record for activation for this user. So I have a stored procedure (work in progress) ... are my assumptions correct? will it lock the record for the user trying to login in the users table thus locking any further accesses to it until the transaction is finished?

CREATE TABLE dbo.UserAuthorizations (
UserAuthorizationID UNIQUEIDENTIFIER NOT NULL,
UserID UNIQUEIDENTIFIER NOT NULL,
ApplicationID UNIQUEIDENTIFIER NOT NULL,
DateCreated DATETIME NOT NULL,
DateLastAuthorized DATETIME NOT NULL,
IsValid BIT NOT NULL,

CONSTRAINT [UserAuthorizations.PK] PRIMARY KEY CLUSTERED (UserAuthorizationID),
CONSTRAINT [UserAuthorizations.UserID.FK] FOREIGN KEY (UserID) REFERENCES dbo.Users(UserID),
CONSTRAINT [UserAuthorizations.ApplicationID.FK] FOREIGN KEY (ApplicationID) REFERENCES dbo.Applications(ApplicationID),
)

CREATE PROCEDURE dbo.LoginUser (@applicationID UNIQUEIDENTIFIER, @username VARCHAR(32), @password VARCHAR(16)) AS
SET NOCOUNT ON

DECLARE @error INT, @rowcount INT
DECLARE @userID UNIQUEIDENTIFIER, @key UNIQUEIDENTIFIER

IF @username IS NULL
RAISERROR('Argument null: @username.', 16, 1) WITH SETERROR
ELSE IF @password IS NULL
RAISERROR('Argument null: @password.', 16, 2) WITH SETERROR
ELSE IF @applicationID IS NULL
RAISERROR('Argument null: @applicationID.', 16, 3) WITH SETERROR
ELSE IF NOT EXISTS(SELECT * FROM dbo.Applications WHERE ApplicationID = @applicationID)
RAISERROR('The application is not maintained by this system.', 16, 4) WITH SETERROR
ELSE IF NOT EXISTS(SELECT * FROM dbo.Users WHERE Name = @username)
RAISERROR('The user name "%s" does not exist.', 16, 5, @username) WITH SETERROR
ELSE IF NOT EXISTS(SELECT * FROM dbo.Users WHERE Name = @username AND Password = @password)
RAISERROR('The password is incorrect for the user "%s".', 16, 6, @username) WITH SETERROR

IF @@ERROR <> 0 RETURN -1

SET @key = NEWID()

SET TRANSACTION ISOLATION LEVEL SERIALIZABLE

BEGIN TRANSACTION

SELECT @userID = UserID
FROM dbo.Users
WHERE Name = @username

IF EXISTS(SELECT * FROM dbo.UserAuthorizations WHERE UserID = @userID AND IsValid = 1)
BEGIN
UPDATE dbo.UserAuthorizations
SET IsValid = 0
WHERE UserID = @userID

SELECT @error = @@ERROR, @rowcount = @@ROWCOUNT

IF @error <> 0 OR @rowcount < 1
BEGIN
ROLLBACK TRANSACTION

RAISERROR('Could not reset the current authorization.', 16, 7) WITH SETERROR

RETURN -1
END
END

INSERT INTO dbo.UserAuthorizations (UserAuthorizationID, UserID, ApplicationID, DateCreated, DateLastAuthorized, IsValid) VALUES (@key, @userID, @applicationID, GETDATE(), GETDATE(), 1)

SELECT @error = @@ERROR, @rowcount = @@ROWCOUNT

IF @error <> 0 OR @rowcount <> 1
BEGIN
ROLLBACK TRANSACTION

RAISERROR('LoginUser failed for an unknown reason.', 16, 8) WITH SETERROR

RETURN -1
END

COMMIT TRANSACTION

SELECT @key AS UserAuthroizationID, @userID AS UserID

RETURN 0
GO

adweigert
Starting Member

22 Posts

Posted - 2003-09-30 : 20:31:42
Ok, I think I have it ... playing with locks ... i wanted the single user row to get locked because that should block any other incoming login requests ... (i use NOLOCK in all the other users selects to ignore this lock) ... here's the end result ... i successfully logged in as two different users without blocking issues ... but when i tried to login as the same user the second request lbocked until the first finished ...

CREATE PROCEDURE dbo.LoginUser (@applicationID UNIQUEIDENTIFIER, @name VARCHAR(32), @password VARCHAR(16)) AS
SET NOCOUNT ON

DECLARE @error INT, @rowcount INT
DECLARE @userID UNIQUEIDENTIFIER, @key UNIQUEIDENTIFIER

IF @name IS NULL
RAISERROR('Argument null: @name.', 16, 1) WITH SETERROR
ELSE IF @password IS NULL
RAISERROR('Argument null: @password.', 16, 2) WITH SETERROR
ELSE IF @applicationID IS NULL
RAISERROR('Argument null: @applicationID.', 16, 3) WITH SETERROR
ELSE IF NOT EXISTS(SELECT * FROM dbo.Applications WHERE ApplicationID = @applicationID)
RAISERROR('The application is not maintained by this system.', 16, 4) WITH SETERROR
ELSE IF NOT EXISTS(SELECT * FROM dbo.Users WITH (NOLOCK) WHERE Name = @name)
RAISERROR('The user name "%s" does not exist.', 16, 5, @name) WITH SETERROR
ELSE IF NOT EXISTS(SELECT * FROM dbo.Users WITH (NOLOCK) WHERE Name = @name AND Password = @password)
RAISERROR('The password is incorrect for the user "%s".', 16, 6, @name) WITH SETERROR

IF @@ERROR <> 0 RETURN -1

SET @key = NEWID()

SET TRANSACTION ISOLATION LEVEL READ COMMITTED

BEGIN TRANSACTION

SELECT @userID = UserID
FROM dbo.Users WITH (ROWLOCK)
WHERE Name = @name

IF EXISTS(SELECT * FROM dbo.UserAuthorizations WITH (NOLOCK) WHERE UserID = @userID AND IsValid = 1)
BEGIN
UPDATE dbo.UserAuthorizations
SET IsValid = 0
WHERE UserID = @userID

SELECT @error = @@ERROR, @rowcount = @@ROWCOUNT

IF @error <> 0 OR @rowcount < 1
BEGIN
ROLLBACK TRANSACTION

RAISERROR('Could not reset the current authorization.', 16, 7) WITH SETERROR

RETURN -1
END
END

INSERT INTO dbo.UserAuthorizations (UserAuthorizationID, UserID, ApplicationID, DateCreated, DateLastAuthorized, IsValid) VALUES (@key, @userID, @applicationID, GETDATE(), GETDATE(), 1)

SELECT @error = @@ERROR, @rowcount = @@ROWCOUNT

IF @error <> 0 OR @rowcount <> 1
BEGIN
ROLLBACK TRANSACTION

RAISERROR('LoginUser failed for an unknown reason.', 16, 8) WITH SETERROR

RETURN -1
END

WAITFOR DELAY '00:00:20'

COMMIT TRANSACTION

SELECT @key AS UserAuthroizationID, @userID AS UserID

RETURN 0
GO
Go to Top of Page
   

- Advertisement -