在数据库并发情况下避免插入重复数据的一个解决方法

目前公司的项目中碰到一个情况:需要向一个数据表table1中插入记录,该表的结构类似于下面的定义:

列名 类型是否允许为空
Idintno
Areastringno
AreaIndexintno
Namestringno

其中Name的值由Area和AreaIndex拼接而成,形式类似于“Area+AreaIndex”。对于相同的Area,AreaIndex从1开始计数,所以对于Area分别为“AA”,“BB”,“CC”的情况,Name的值类似下面这样:

AA001 AA002 BB001 AA003 BB002 CC001这种形式。

当插入新值的时候,需要判断数据表中该Area的最大AreaIndex,在此基础上加1做为新行的AreaIndex,同时拼接Name到数据库中。在数据库并发的情况下,会出现大量相同记录的情况。

目前想到的一个比较好的解决方法就是:

1,创建一个新表Table2来存储Area的最大AreaIndex,当插入新记录时,从新表中获取最大AreaIndex,加一作为新记录的AreaIndex,同时更新新表的最大AreaIndex。

2,创建一个新的存储过程来添加记录到表中。在该存储过程中,先查询Table2并锁定该表。获取插入记录对应Area的最大AreaIndex并更新Table2中的记录后,插入记录到Table1中。存储过程的代码类似下面这样:

BEGIN
      BEGIN TRAN
      DECLARE @MaxAreaIndex int      
      

      --查询并锁定Table2
      SELECT @MaxAreaIndex = AreaIndex
      FROM    Table2 WITH (TABLOCKX)
      WHERE  Area= @Area
      

      --获取到最大的AreaIndex后,更新Table2
      IF @MaxAreaIndex IS NULL
          BEGIN

     --如果Table2中没有记录,则新增一条记录
             SET @MaxAreaIndex = 1
             INSERT INTO [Table2]
                   ([MaxAreaIndex] ,[Area])
             VALUES
                   (@MaxAreaIndex, @Area)
          END
      ELSE

    BEGIN    

               SET @MaxAreaIndex = @MaxAreaIndex  + 1
               UPDATE Table2
               SET       MaxAreaIndex = @MaxAreaIndex
               WHERE  Area = @Area

    END
    
     INSERT INTO Table1
           ([Name] ,[Area] ,[AreaIndex])
     VALUES
           (@Area+ RTRIM(LTRIM(STR(@MaxAreaIndex))) ,@Area ,@MaxAreaIndex)
    
    COMMIT TRAN

 

关键的代码在:

      SELECT @MaxAreaIndex = AreaIndex
      FROM    Table2 WITH (TABLOCKX)
      WHERE  Area= @Area

当在存储过程中对表Table2进行加锁后,其他对该存储过程的调用就必须等待前一次执行完成并释放对表的锁定后才能继续执行。

在Area不是很多的情况下,效率没有大的影响。

 

 

 

 

 

 

转载于:https://www.cnblogs.com/caoyawu/p/3841370.html

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值