日期:2014-05-16 浏览次数:20889 次
begin tran
select top 1 * from dbo.t with(readpast) where id>10
commit
--关于在SQL Server中生成流水号的方法的讨论
--第一种方法
--有些是用种子表,
--在种子表中记录流水号,产生新的流水号后更新种子表的"种子数据",
--也见过比较低级的,种子表的值用自增列实现,每次插入数据,取种子表的自增列的值,
--一开始还不理解,觉得没必要,后来发现他们是为了防止并发,产生重复的流水号
--后来在想,防止并发产生重复的流水号,必须用种子表吗?
--第二种方法
--有些是用函数,因为流水号有一定的组合规律,放在函数中,结合业务表的数据,组合生成,
--先不说第第二种做法,对于第一种做法,
--原因无外乎是放在一个事物中,防止因为并发产生相同的流水号
--那么,原因知道了,有必要为了产生流水号,去增加一个表?
--怪不得有些系统,看起来表挺多的,一看,尼玛冗余一大堆
--这里实现不用种子表,生成不重复序号的方法,
--重复的原因就是因为在"同一时刻"没有把"资源锁定"
--那么,为了我们可不可以直接锁定业务表呢?
--随便创建一张表,当做是业务表,这里为了简化,流水号为整数类型,主要为了说明实现方法
--试一下updlock吧,在查询max(id)时候,锁定表,在当前事务提交之前,其他事物无法获取max(id)的值
--测试一下
drop table t
create table t
(
id int,
remark varchar(50)
--其他字段不做一一列举,
)
insert into t values (1,'A');
dbcc tran
begin tran
declare @i int
select @i=max(id) from t with(UPDLOCK);
--种子生成了
--下面该具体的业务操作了
--暂时不提交这个事务,其他链接无法获取max(id)
commit;
--另外开一个窗口,select max(id) 是要被阻塞的
--除非当前事务提交
--有人会质疑select max(id)的效率,
--其实ID列上加上索引的话,select max(id)的效率完全不用担心
--这样,既可以生成不重复的流水号,又省下了一张表,可以将精力集中于业务逻辑
--避免建立一些蛋疼的表
--另外,也见过不少人,照猫画虎,人家用种子表生成流水号,我也这样用
--可惜生成种子的时候,连事物都不开,这种方式,连种子表的本意都给误会了
update tbAllId
set curid=curid+1
output curid
where app=123
declare @i int,@v varchar(50)
declare @t table(fmax int,flast datetime)
declare @td varchar(50)
declare @s datetime
set @s=getdate()
set @v=convert(varchar(50),@s,120)
print @v
set @v=left(@v,18