У меня есть страница в нашей интрасети, которая отправляет запросы в CGI-скрипт Perl.Этот скрипт, в свою очередь, вызывает хранимую процедуру в БД SQL Server, которая проверяет, существует ли объект с определенными атрибутами.Если это так, storproc возвращает идентификатор инструмента, если нет, он создает новый инструмент и возвращает идентификатор этого нового инструмента.Хранимая процедура создает транзакцию, а также использует with (TABLOCKX)
в операторе вставки.Для удобства, когда указанный пользователь одновременно отправляет несколько запросов, веб-страницы отправляют запросы в сценарий perl асинхронно.Я подумал, что когда будет отправлено несколько запросов, требующих нового инструмента, первый, ударивший storproc, запустится, заблокирует таблицу, создаст новый инструмент, снимет блокировку, а затем последующие вызовы storproc будут известныновый инструмент и использовать его.На практике я увидел, что будет несколько запросов на создание нового инструмента, а остальные будут использовать самый последний.Я пытался использовать setTimeout на стороне клиента для распределения запросов, но, похоже, это не имеет значения.Любые идеи относительно того, что я могу делать неправильно?
Вот код хранимой процедуры:
CREATE PROCEDURE [dbo].[CreateFutures]
@code varchar(5),
@month int,
@year int,
@currency varchar(3)
AS
BEGIN
SET NOCOUNT ON;
BEGIN TRANSACTION
declare @ticker varchar(7)
declare @yearCode char(1)
declare @res as Table (id int)
declare @n as int
set @yearCode = convert(char(1), @year % 10)
set @ticker = (
select @code + futures + @yearCode
from FuturesMonthCodes
where month = @month
)
insert into @res
select top 1 instrument
from InstrumentFutures // This is a view that joins InstrumentText and InstrumentNumber data
where ticker = @ticker
and code = @code
and month = @month
and year = @year
and currency = @currency
order by instrument
set @n = (select COUNT(id) from @res)
if @n = 0
begin
print 'Creating Future'
declare @id int
declare @stamp datetime
set @stamp = CURRENT_TIMESTAMP
insert into Instrument with (TABLOCKX) (insertTime) values (@stamp)
set @id = (select SCOPE_IDENTITY());
insert into InstrumentText (instrumentId, name, value) values (@id, 'type', 'futures')
insert into InstrumentText (instrumentId, name, value) values (@id, 'ticker', @ticker)
insert into InstrumentText (instrumentId, name, value) values (@id, 'code', @code)
insert into InstrumentText (instrumentId, name, value) values (@id, 'currency',@currency)
insert into InstrumentNumber (instrumentId, name, value) values (@id, 'month', @month)
insert into InstrumentNumber (instrumentId, name, value) values (@id, 'year', @year)
insert into @res (id) values (@id)
end
commit transaction
if @n = 0 --instrument created
select top 1 id, 1 from @res order by id
else --returning existing instrument
select top 1 id, 0 from @res order by id
END