多线程调用存储过程问题

来源:互联网 发布:sql注入技术详解 编辑:程序博客网 时间:2024/05/21 21:38

 

        书写一存储过程:proc_importurltodb;

        该存储过程的主要作用是将给定的URL拆分,以类链表的方式多个表分层次给予存储。

        主要的流程为: 首先查询表,判断要插入的数据是否存在;如果存在,则返回相应的orderid;如果不存在,则插入数据,并且返回插入后的orderid。

 

 

        由于数据量较大(千万级),因此程序中采用了ADO+多线程调用存储过程的方式,结果跑了一天的数据发现出现问题了;

由于多线程问题,可能会出现线程1插入同样数据,与此同时线程2插入同样数据,但由于库中没有要插入的数据,因此线程1和线程2会分别将数据给予插入,结果为同样的数据却出现了重复。。。。

 

 

      呵呵,每天都例行公事,出点棘手的问题。没办法只能解决处理了:

 

      方法一:数据库锁定

 

       由于是多线程调用存储过程,而整个插入逻辑都由存储过程实现,因此如果需要锁定数据,仅能靠存储过程中实现。

通过查看sql server 帮助手册以及试验,发现采用

 

     begin tran

 

     SET @OrderNum = (SELECT  top 1 urldomainorderid FROM UrlDomainTable with(tablockx)   WHERE urlinfo = @UrlDomain)

 

     commit tran

 

  的方式可以确保插入时为唯一条数据。

 

       但却也出现新问题了: 由于采用的是表级锁定, 在存储过程的整个事务中,其它事务无法使用该表;而整个系统的其它表则会同时使用该表。。。所以再换思路。

 

 

        方法二:多线程同步

 

         该方法需要对含有同样数据的信息进行多线程同步处理,主要思路为多线程插入数据时,判断是否为同样数据,如果同样,则同步。

        实现复杂,不想实现~~·

 

 

         方法三:唯一约束+错误处理

 

       对插入数据表的特定列创建唯一约束,对于可能会涉及到多个列的,则创建组合唯一约束。

当出现相同数据多次插入时,则会由于唯一约束问题,而插入失败。此时通过TRY ....CATCH即可捕获错误信息,通过对错误信息判断,进而可以再次插入数据,而此时由于数据已经存在因此也就不存在多次插入的可能。

 

 

 

         呵呵,问题总算得到解决,又得到一个教训。。。700多W白跑了。

 

 

         不知道,各位看有没有其它更好的办法?