如我有表
班级 
ID  名称 最多人数
1   一班 4
学生表
ID 名字 所属班级ID
1  张三 1
2  李四 1
-------------------
然后现在新生进行报名的时候,比如现在有很多进行同时操作
比如现在有两个地方进行同时操作
A启动事务
B启动事务
A取得了一班还可以再加2人他要进行添加
但他还没有对学生表进行Insert的时候
B也查询出一班也可以添加2个人
这进A进行添加了2个人
A结束事务
B也会添加两人人
B结束事务但是这样子下来的话数据就会为
ID  名称 最多人数
1   一班 4
学生表
ID 名字 所属班级ID
1  张三 1
2  李四 1
3  小王 1
4  小李 1
5  小张 1
6  小红 1
------------------
这个时候就是会是6条数据出现人数不对
要怎么办呢
谢谢

解决方案 »

  1.   

    楼主可以试试表锁定,当A对一班进行操作的时候,锁定A表,此时其他用户无法操作。
    当A操作完毕后,B用户再进行操作前,先查询一班是否可以添加。可以添加则再添加。、表锁定:with(holdlock)
      

  2.   

    这个通过前台自己写代码来搞了.不要指望SQL SERVER了.
      

  3.   

    在每一个事务中加上架构锁
    begin tran
    dbcc lockobjectschema(表名)
    select ..
    insert ...commit tran
      

  4.   

    改一下处理方法就好了, 类似下面的BEGIN TRAN
    UPDATE 班级人数表 SET
    人数 = 人数 + 1
    WHERE 人数 > 0 IF @@ROWCOUNT = 0
    BEGIN
    ROLLBACK TRAN
    RAISERROR('人数已满', 16, 1)
    END
    ELSE
    BEGIN
    INSERT 班级人员表 VALUES('张三')
    COMMIT TRAN
    END
      

  5.   

    取了再判断, 这样在取的时候就要加锁
    所以不如直接更新, 判断一下更新的结果就知道这个班的人数有没有满了, 而且 update 的时候自动加锁, 可以避免并发冲突WHERE 人数 > 0
    这个应该还要加一个"班级='xx'"的条件
      

  6.   

    RE:邹大哥可以解决这个问题
    但是我的还有一个问题比如
    ID  名称 最多人数 
    1   一班 4 
    学生表 
    ID 名字 所属班级ID 这时学生表里面没有人
    A要插入3个 B要插入三个
    如果照上面的话
    应该是A插入3个,B可以插入1个但这样不符合我的要求,
    因为我要当B不够三个的时候就不让插了谢谢
      

  7.   

    RE:取了再判断, 这样在取的时候就要加锁 
    ----------------------
    但这样听说会很容易造成死锁
    RE:所以不如直接更新, 判断一下更新的结果就知道这个班的人数有没有满了, 而且 update 的时候自动加锁, 可以避免并发冲突 
    ---------------------
    这样就会造成一批人里面可能只插入了某些人
    问:
    能不能在A启动事特的时候就
    update 班表 最多人数=最多人数 where ID=1
    这样子更新显示数据没有更改,那他会不会加锁呢
    如果会的话我们再进行 查询能添加多少个人 再添加人就可以防止别人也来查询这个表
    也就相当于没取之前就加锁 可行不可行谢谢
      

  8.   

    RE:表锁定:with(holdlock) 
    听说容易出现死锁那我问:
    用 update 班表 最多人数=最多人数 where ID=1 
    这样他会不会自动加锁呢谢谢
      

  9.   

    而且的话,你要加几个人到团中, 这个人数你是知道的, 所以你完全可以这样
    DECLARE
    @要加入的人数 int
    SET
    @要加入的人数 = 10
    BEGIN TRAN
    UPDATE 团 SET
    人数 = 人数 + @要加入的人数
    WHERE 人数 >= @要加入的人数 IF @@ROWCOUNT = 0
    BEGIN
    ROLLBACK TRAN
    RAISERROR('人数已满', 16, 1)
    END
    ELSE
    BEGIN
    INSERT 人员表
    SELECT '张三' UNION ALL
    SELECT '李四' UNION ALL
    SELECT '王五'  COMMIT TRAN
    END
      

  10.   

    考虑仔细一点应该这样, 人员应该和团关联起来, 只能放到一个团中DECLARE
    @要加入的人数 int,
    @团的编号 int
    SET
    @要加入的人数 = 10
    BEGIN TRAN
    SET ROWCOUNT = 1 -- 只能加入一个团
    UPDATE 团 SET
    人数 = 人数 + @要加入的人数,
    @团的编号 = 编号
    WHERE 人数 >= @要加入的人数 IF @@ROWCOUNT = 0
    BEGIN
    ROLLBACK TRAN
    SET ROWCOUNT 0
    RAISERROR('人数已满', 16, 1)
    END
    ELSE
    BEGIN
    SET ROWCOUNT 0
    INSERT 人员表(
    姓名, 团号)
    SELECT '张三', @团的编号 UNION ALL
    SELECT '李四', @团的编号 UNION ALL
    SELECT '王五', @团的编号 COMMIT TRAN
    END
      

  11.   

    如果要删除的话,也只有删除"一堆",不能一个个地删,是吗? 问题好复杂呀!
    所以我觉得你的具体问题还应当是如下:不管能否编团,旅游小组的信息都可以建立入库,然后根据其它信息再组团.旅游团结构如下:旅游团编号  旅游小组编号  序号 姓名
        1         1         1  AA1
        1         1         2  AA2
        1         1         3  AA3
        1         1         4  AA4
        1         1         5  AA5
        1         2         1  AA6
        1         2         2  AA7
        1         2         3  AA8
        1         2         4  AA9
                  3         1  AA10
                  3         2  AA11
                  3         3  AA12
                  3         4  AA13
                  3         5  AA14如果旅游团的最大人数是9的话,小组1+小组2  或  小组3+小组2  都可以是合理的你用一个班级和学生做举例,将问题的实质全改变了.