我正在创建一个卖票的应用程序,我有一张可以买到票的桌子
id | serial | sold
-------------------------------
1 | 000001 | false
2 | 000002 | false
3 | 000003 | true当用户请求一张票时,应用程序选择一张票证并将其标记为已售出。
我的问题是:如何管理这个表,防止将同一张票卖给不同的用户,因为他们知道同时会有数百个请求?
我正在考虑锁定,但当事务的行被锁定时,如果另一个事务请求锁,则必须等到第一个事务完成并更新已售出的行时,第二个事务将返回票证已售出的状态。现在,如果发现第二个事务已被锁定,如何将其重定向到另一个行?
编辑
根据Paul的评论,我创建了一个存储过程
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)但是,我需要确定,如果两个事务同时出现,第二个事务会发生什么?它会跳过这一行并移到下一行吗?还是等待第一个事务完成,然后选择同一行?
发布于 2015-02-02 11:09:53
我将使用一个简单的对象锁定项目,并确保它是私有/静态的。这将允许在类的所有实例之间共享其状态,同时防止从类外部修改对象。
有关错误处理和锁,请参阅
In C# how can I safely exit a lock with a try catch block inside?
为了支持//Log异常锁,将自动释放异常锁。
这段代码还没有经过测试,但是它应该给你一个好的开始。
public class NextTicketinSequence
{
private static int _LastTicketNumber;
private static object _TicketLock;
public static NextTicketinSequence()
{
NextTicketinSequence._LastTicketNumber = 0;
}
public static int GetNextTicketNumber()
{
int ticketId = 0;
try
{
lock(_TicketLock)
{
NextTicketinSequence.LoadLastTicketSold();
ticketId = NextTicketinSequence._LastTicketNumber + 1;
}
}
Catch(Exception ex)
{
//Log exception lock will be released automaticaly
}
return ticketId
}
public static void LoadLastTicketSold
{
//Code to get the last ticket marked as sold
}
}https://stackoverflow.com/questions/28274150
复制相似问题