【发布时间】:2015-02-02 09:04:57
【问题描述】:
我正在创建一个销售门票的应用程序,我有一张可用门票的表格
id | serial | sold
-------------------------------
1 | 000001 | false
2 | 000002 | false
3 | 000003 | true
当用户请求一张票时,应用会选择一张票并将其标记为已售出。
我的问题是:如何管理这张表并防止将同一张票卖给不同的用户,而知道同时会有数百个请求?
我正在考虑锁定,但是当该行被锁定以进行事务时,如果另一个事务请求锁定,它必须等到第一个事务完成并将该行更新为已售出,然后第二个事务将返回该票已售出。现在,如果发现该行被锁定,我如何将第二个事务重定向到不同的行?
编辑
根据 Paul Zahra 的评论,我创建了一个存储过程
DECLARE @id varchar(MAX)
SELECT @id = (
SELECT top(1) [Id]
FROM [dbo].[AvailableItems] WITH (ROWLOCK, UPDLOCK)
WHERE ([Sold] = 0) )
UPDATE [dbo].[AvailableItems]
SET [Sold] = 1
WHERE [Id] = @id
SELECT [Id], [Serial], [CreateDate], [AvailableTo]
FROM [dbo].[AvailableItems]
WHERE ([Id] = @id)
但是我需要确定如果两个交易同时发生,第二个交易会发生什么?它会跳过这一行并移动到下一行吗?还是等待第一个事务完成然后选择同一行?
【问题讨论】:
-
有人买票的时候能直接生成连载吗?检查该系列尚未售出并将其标记为已售出。
-
不行,因为我要导出表格到入口系统
-
好的。为什么不简单地循环表格直到你达到最大 id 值,寻找一个 sold = false ?这有点低效,那为什么不'select * where sold = false'呢?如果由于竞争条件而失败,那么循环?
-
这很好,但是会延迟请求,锁定怎么样,你能帮我写代码吗?
-
读一读...现在在这里*.com/questions/3767328/how-to-perform-a-row-lock 检测一行是否被锁定,恐怕是非常困难*.com/questions/11464317/…
标签: transactions sql-server-2008-r2