日期:2014-05-17  浏览次数:20474 次

sqlserver 主键生成策略的问题
想问问各位大侠 你们用sqlserver的时候 是怎么生成主键的
我这里的话 表的主键是用存储过程生成 一般是
日期+6位号 比如今天的生成应该是121023000001 ,121023000002 ,121023000003 等,到了明天就是 121024000001,121024000002等
每个表都是这样通过一个存储过程来生成主键,但是随着并发量的增加 程序就会出现 阻塞、死锁等问题。
有时候还会丢数据 这个是非常大单的。
现在有没有什么好的其他办法。
我能想到的 1 换数据库 sql2000 升级到 sql2005或 2008 
           2 换新的服务器 我这个是IBM 3650 志强2.2G 8G内存 
           3 根本上换这个主键生成的策略 
              因为生成主键的时候 是要锁表的,一旦并发,就问题来了。如果改成系统自动获取主键不知道行不行,是不是就没有 阻塞、死锁 这些问题了。


           现在头都大了 麻烦各位高手指点迷津!谢谢!

------最佳解决方案--------------------
通过升级版本来完全避免死锁等问题是不现实的,由于关系数据库需要保证数据一致性,所以等待甚至阻塞是无法避免的。

主键上的日期部分可以通过convert/cast对getdate来转换得到。后面那些自增的标识,可以通过存储过程里面的IDENT_CURRENT/SCOPE_IDENTITY函数来获取最大,然后加1.

http://blog.csdn.net/dba_huangzj/article/details/7685162
------其他解决方案--------------------
引用:
通过升级版本来完全避免死锁等问题是不现实的,由于关系数据库需要保证数据一致性,所以等待甚至阻塞是无法避免的。

主键上的日期部分可以通过convert/cast对getdate来转换得到。后面那些自增的标识,可以通过存储过程里面的IDENT_CURRENT/SCOPE_IDENTITY函数来获取最大,然后加1.

http://blog.csdn.net/dba_huangzj/artic……



CREATE PROCEDURE CreateID 
@TableName varchar(50) 

AS
begin   
    declare @LastID varchar(50)
    declare @CreateID varchar(12) 
    SET LOCK_TIMEOUT 3600
    
    begin TRANSACTION
        select @LastID = CreateID from CreateID with (rowlock)  where TableName = @TableName  
        if @@ERROR<>0
        begin
            ROLLBACK TRANSACTION
            set @CreateID=''
            RETURN
        end
        set @CreateID =convert(char(6),getdate(),12)+'000001'
        if @LastID is null
            begin
                set @CreateID=convert(char(6),getdate(),12)+'000001'
                insert CreateID (TableName,CreateID) values( @TableName,@CreateID)
            end 
        else
            begin
           if left(@LastID,6)  = convert(char(6),getdate(),12)
                  begin