Sql Server - 计数器列,即使事务回滚也会递增

问题描述 投票:2回答:1

我需要管理产品生命周期中每年的增量计数器(协议号)。该值在每年内必须是唯一的,我需要一旦计数器递增,它就不能回滚。

如果我创建一个存储的proc来创建它的内部事务,当我的后端在它自己的事务中调用它并失败时,计数器返回到前一个值。

有没有一种方法来增加计数器,即使所有事务都失败了,比如标识列呢?

谢谢,大卫

附:我不能使用标识列,因为我不知道我需要管理多少个计数器。我也不能使用序列,我必须使用SQL2008数据库:-(

sql-server transactions identity-column
1个回答
0
投票

这是一个使用环回链接服务器连接的解决方案。这允许更新当前事务上下文之外的表:

use TEST; -- assume the database is named TEST

create table SeqNo (
  SeqName nvarchar(10) not null primary key, 
  LastValue int default 0
);
insert into SeqNo (SeqName) values ('A'),('B');

create table Protocol (
  id int not null primary key identity(1, 1), 
  SeqName nvarchar(10) not null, 
  SeqNo int not null, 
  SomeText nvarchar(100)
);

GO

EXEC master.dbo.sp_addlinkedserver @server = N'MyLoopback',
                                   @srvproduct = N'', 
                                   @datasrc = @@SERVERNAME, -- use own server
                                   @provider = N'SQLOLEDB',
                                   @catalog=N'TEST';

GO

EXEC master.dbo.sp_serveroption @server=N'MyLoopback', @optname=N'remote proc transaction promotion', @optvalue=N'false';
EXEC master.dbo.sp_serveroption @server=N'MyLoopback', @optname=N'rpc', @optvalue=N'true';
EXEC master.dbo.sp_serveroption @server=N'MyLoopback', @optname=N'rpc out', @optvalue=N'true';

GO

/* We did the preparation work, now do a test... */

SET TRANSACTION ISOLATION LEVEL READ COMMITTED;
BEGIN TRANSACTION; 

declare @SeqName nvarchar(10);
set @SeqName = N'A';
declare @NewSeqNo int;

exec (N'SET TRANSACTION ISOLATION LEVEL SERIALIZABLE;
BEGIN TRANSACTION; 
declare @tmp table (NewValue int);
update SeqNo set LastValue = LastValue + 1 output inserted.LastValue into @tmp where SeqName = ?;
select top 1 ?=NewValue from @tmp;
COMMIT TRANSACTION;', @SeqName, @NewSeqNo output) at MyLoopback;

insert into Protocol (SeqName, SeqNo, SomeText) values (@SeqName, @NewSeqNo, N'Whatever you want');

ROLLBACK TRANSACTION; -- alternatively "COMMIT TRANSACTION" to have the row in Protocol persistent

select * from Protocol;
select * from SeqNo; -- became updated, even if rolled back (outer) transaction above
© www.soinside.com 2019 - 2024. All rights reserved.