日期:2014-05-18  浏览次数:20546 次

请问这种情况会出现吗,如何避免,最好有代码,万分焦急
SQL code
SELECT @red=COUNT(*) FROM Authority WHERE roomID=@roomID AND authorityID=2
        IF(@red>19)
            RETURN 2--管理员数目满了直接返回



我写了个存储过程,管理员数目最多20个,可是有19个人的时候,两个人同时操作,然后恰好到了这句话都查出来是19,那会不会都插入表中了,结果就有21名管理员了,但规定是最多只能有20名管理员。

------解决方案--------------------
SQL code
USE CSDN
go

CREATE TABLE Authority 
(
    ID INT IDENTITY,
    [NAME] VARCHAR(10),
    [PASSWORD] VARCHAR(10)
)
GO

--#1.用表锁
BEGIN TRAN
    DECLARE @count INT
    SELECT @count=COUNT(*) FROM Authority WITH(TABLOCKX) --可以保证同时只有一个线程可以访问Authority表
    IF(@count < 20)
    BEGIN
        INSERT Authority
        SELECT 'test'+CAST(@count AS VARCHAR), '123456'
    END
COMMIT TRAN

------解决方案--------------------
SQL code
--#2.锁表影响的范围比较大,效率也不好。可增加一个辅助表来解决
CREATE TABLE LockTable
(
    TableName VARCHAR(100),
    tcount INT
)
INSERT LockTable VALUES('Authority', 0)
GO
--SQL如下:
BEGIN TRAN
    UPDATE LockTable
    SET tcount = tcount+1
    WHERE TableName = 'Authority' --此句放在一个事务中,保证了添加管理员进程必须排队
    
    DECLARE @count INT
    SELECT @count=COUNT(*) FROM Authority
    IF(@count < 20)
    BEGIN
        INSERT Authority
        SELECT 'test'+CAST(@count AS VARCHAR), '123456'
    END
COMMIT TRAN