在高并发的系统怎样获取一个全局唯一的编号?

zzxap 2009-05-22 04:59:47
我有一个界面同事保存数据到两个表,一个父表一个子表。
父子表的编号要唯一和对应。
其它用户也要获取一个流水号,用于新增数据。

怎样在高并发的时候获取到全局唯一的编号?

select max(id) 会取到同一个编号


...全文
304 16 打赏 收藏 转发到动态 举报
写回复
用AI写文章
16 条回复
切换为时间正序
请发表友善的回复…
发表回复
饮水需思源 2009-05-23
  • 打赏
  • 举报
回复
用一张单据最大单号表来存放每一种单据的最大编号,每次保存时从此表中读取并加1作为本次保存的最大号,保存成功后再将本次保存的最大编号回写到此表,当然保存时要用事务来处理
hery2002 2009-05-23
  • 打赏
  • 举报
回复
使用数据库事务,隔离事务级别.在数据写入时直接在数据库端操作,
在从系统中抓取一个最大值处理,同时使用存储过程来完成。
Q832198 2009-05-23
  • 打赏
  • 举报
回复
[Quote=引用 13 楼 sparklerl 的回复:]
用GUID号来[/Quote] 这个不错 考虑一下.
sparklerl 2009-05-22
  • 打赏
  • 举报
回复
用GUID号来
jiangshun 2009-05-22
  • 打赏
  • 举报
回复
[Quote=引用 9 楼 zzxap 的回复:]
除了设置递增列和用@@IDENTITY、SCOPE_IDENTITY 和 IDENT_CURRENT

有没有其他方法获取一个唯一编号呢?
[/Quote]

以添加数据的时间来生成一个编号?
JonasFeng 2009-05-22
  • 打赏
  • 举报
回复
我现在的项目就是一个界面 父表和子表一同保存的。
也没见有什么问题呀。

只是要在保存的时候判断,系统中该信编号是否存在,如果存在,系统自动取最新的编号。

存储过程用事务,用@@IDENTITY就可以了。这样不会有什么问题的。
zzxap 2009-05-22
  • 打赏
  • 举报
回复
[code=SQL]
@@IDENTITY
返回最后插入的标识值。

语法
@@IDENTITY

返回类型
numeric

注释
在一条 INSERT、SELECT INTO 或大容量复制语句完成后,@@IDENTITY 中包含此语句产生的最后的标识值。若此语句没有影响任何有标识列的表,则 @@IDENTITY 返回 NULL。若插入了多个行,则会产生多个标识值,@@IDENTITY 返回最后产生的标识值。如果此语句激发一个或多个执行产生标识值的插入操作的触发器,则语句执行后立即调用 @@IDENTITY 将返回由触发器产生的最后的标识值。若 INSERT 或 SELECT INTO 语句失败或大容量复制失败,或事务被回滚,则 @@IDENTITY 值不会还原为以前的设置。

在返回插入到表的 @@IDENTITY 列的最后一个值方面,@@IDENTITY、SCOPE_IDENTITY 和 IDENT_CURRENT 函数类似。

@@IDENTITY 和 SCOPE_IDENTITY 将返回在当前会话的所有表中生成的最后一个标识值。但是,SCOPE_IDENTITY 只在当前作用域内返回值,而 @@IDENTITY 不限于特定的作用域。

IDENT_CURRENT 不受作用域和会话的限制,而受限于指定的表。IDENT_CURRENT 返回任何会话和任何作用域中为特定表生成的标识值。有关更多信息,请参见 IDENT_CURRENT。


---------------------------------------------------------------

我总结的3种返回最大标识值的方法的不同点:

IDENT_CURRENT 返回为任何会话和任何作用域中的特定表最后生成的标识值。


@@IDENTITY 返回为当前会话的所有作用域中的任何表最后生成的标识值。


SCOPE_IDENTITY 返回为当前会话和当前作用域中的任何表最后生成的标识值。(防止返回触发器中的insert的IDENTITY值)
---------------------------------------------------------------

@@IDENTITY
返回最后插入的标识值。

语法
@@IDENTITY

返回类型
numeric

注释
在一条 INSERT、SELECT INTO 或大容量复制语句完成后,@@IDENTITY 中包含此语句产生的最后的标识值。若此语句没有影响任何有标识列的表,则 @@IDENTITY 返回 NULL。若插入了多个行,则会产生多个标识值,@@IDENTITY 返回最后产生的标识值。如果此语句激发一个或多个执行产生标识值的插入操作的触发器,则语句执行后立即调用 @@IDENTITY 将返回由触发器产生的最后的标识值。若 INSERT 或 SELECT INTO 语句失败或大容量复制失败,或事务被回滚,则 @@IDENTITY 值不会还原为以前的设置。

在返回插入到表的 @@IDENTITY 列的最后一个值方面,@@IDENTITY、SCOPE_IDENTITY 和 IDENT_CURRENT 函数类似。

@@IDENTITY 和 SCOPE_IDENTITY 将返回在当前会话的所有表中生成的最后一个标识值。但是,SCOPE_IDENTITY 只在当前作用域内返回值,而 @@IDENTITY 不限于特定的作用域。

IDENT_CURRENT 不受作用域和会话的限制,而受限于指定的表。IDENT_CURRENT 返回任何会话和任何作用域中为特定表生成的标识值。有关更多信息,请参见 IDENT_CURRENT。

示例
下面的示例向带有标识列的表中插入一行,并用 @@IDENTITY 显示在新行中使用的标识值。

INSERT INTO jobs (job_desc,min_lvl,max_lvl)
VALUES ('Accountant',12,125)
SELECT @@IDENTITY AS 'Identity'


  SQL Server 2000中,有三个比较类似的功能:他们分别是:SCOPE_IDENTITY、IDENT_CURRENT 和 @@IDENTITY,它们都返回插入到 IDENTITY 列中的值。
  IDENT_CURRENT 返回为任何会话和任何作用域中的特定表最后生成的标识值。IDENT_CURRENT 不受作用域和会话的限制,而受限于指定的表。IDENT_CURRENT 返回为任何会话和作用域中的特定表所生成的值。
  @@IDENTITY 返回为当前会话的所有作用域中的任何表最后生成的标识值。
  SCOPE_IDENTITY 返回为当前会话和当前作用域中的任何表最后生成的标识值
  SCOPE_IDENTITY 和 @@IDENTITY 返回在当前会话中的任何表内所生成的最后一个标识值。但是,SCOPE_IDENTITY 只返回插入到当前作用域中的值;@@IDENTITY 不受限于特定的作用域。
  例如,有两个表 T1 和 T2,在 T1 上定义了一个 INSERT 触发器。当将某行插入 T1 时,触发器被激发,并在 T2 中插入一行。此例说明了两个作用域:一个是在 T1 上的插入,另一个是作为触发器的结果在 T2 上的插入。
  假设 T1 和 T2 都有 IDENTITY 列,@@IDENTITY 和 SCOPE_IDENTITY 将在 T1 上的 INSERT 语句的最后返回不同的值。
  @@IDENTITY 返回插入到当前会话中任何作用域内的最后一个 IDENTITY 列值,该值是插入 T2 中的值。
  SCOPE_IDENTITY() 返回插入 T1 中的 IDENTITY 值,该值是发生在相同作用域中的最后一个 INSERT。如果在作用域中发生插入语句到标识列之前唤醒调用 SCOPE_IDENTITY() 函数,则该函数将返回 NULL 值。
  而IDENT_CURRENT('T1') 和 IDENT_CURRENT('T2') 返回的值分别是这两个表最后自增的值。
  ajqc的实验:(40条本地线程,40+40条远程线程同时并发测试,插入1200W行),得出的结论是:
  1.在典型的级联应用中.不能用@@IDENTITY,在CII850,256M SD的机器上1W多行时就会并发冲突.在P42.8C,512M DDR上,才6000多行时就并发冲突.
  2.SCOPE_IDENTITY()是绝对可靠的,可以用在存储过程中,连触发器也不用建,没并发冲突
[/CODE]
zzxap 2009-05-22
  • 打赏
  • 举报
回复
除了设置递增列和用@@IDENTITY、SCOPE_IDENTITY 和 IDENT_CURRENT

有没有其他方法获取一个唯一编号呢?
zzxap 2009-05-22
  • 打赏
  • 举报
回复
insert into t1(name,sex) values (1,2)

select SCOPE_IDENTITY() as aa
zzxap 2009-05-22
  • 打赏
  • 举报
回复
没有设置递增列,sorry
zzxap 2009-05-22
  • 打赏
  • 举报
回复
insert into t1(id,name) values (1,2)

select @@IDENTITY from t1

为什么得到一列null
sdhdy 2009-05-22
  • 打赏
  • 举报
回复
--小F-- 2009-05-22
  • 打赏
  • 举报
回复
@@IDENTITY
昵称被占用了 2009-05-22
  • 打赏
  • 举报
回复
自增字段,插入父表自动保持唯一,插入后用SCOPE_IDENTITY 函数取出刚刚插入的号,用来插入子表,就保证一致了
jiangshun 2009-05-22
  • 打赏
  • 举报
回复
@@IDENTITY、SCOPE_IDENTITY 和 IDENT_CURRENT 函数
jiangshun 2009-05-22
  • 打赏
  • 举报
回复
@@IDENTITY

22,298

社区成员

发帖
与我相关
我的任务
社区描述
MS-SQL Server 疑难问题
社区管理员
  • 疑难问题社区
  • 尘觉
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧