3

我正在实施一场可能有很多同时参赛的比赛。我正在收集一些用户数据,并将其放入一个名为条目的表中。我在一个名为 discountCodes 的表中有另一个预先生成的唯一折扣代码表。然后我为每个条目分配一个。我想我会通过在 discountCodes 表中放置一个条目 id 来做到这一点。

由于可能有很多并发用户,我认为我应该选择第一个未分配的行,然后将条目 ID 分配给该行。我需要确保在选择未分配的行和添加另一个线程找不到同一行的条目 id 之间。

确保该行不会被分配两次的最佳方法是什么?

4

5 回答 5

1

我建议构建一个桥接表,而不是EntryIdDiscountCodes表中使用 anEntryId和 a DiscountCodeIdUnique Constraint在这两个字段上放置一个。

这样,您的入口点在尝试输入重复项时将遇到约束冲突。

于 2013-09-18T15:57:25.867 回答
1

可以做一些事情

以下示例设置会话的事务隔离级别。对于随后的每个 Transact-SQL 语句,SQL Server 将持有所有共享锁,直到事务结束。 来源:MSDN

USE databaseName;
GO
SET TRANSACTION ISOLATION LEVEL REPEATABLE READ;
GO
BEGIN TRANSACTION;
GO
SELECT * 
    FROM Table1;
GO
SELECT * 
    FROM Table2;
GO
COMMIT TRANSACTION;
GO

阅读更多设置交易隔离级别

于 2013-09-18T15:57:44.157 回答
0

您可以尝试使用sp_getapplock并同步写入操作,只需确保它锁定相同的哈希,例如

DECLARE @state    Int

BEGIN TRAN

-- here we're using 1 sec's as time out, but you should determine what the min value is for your instance
EXEC @state = sp_getapplock 'SyncIt', 'Exclusive', 'Transaction', 1000

-- do insert/update/etc...

-- if you like you can be a little verbose and explicit, otherwise line below shouldn't be needed
EXEC sp_releaseapplock 'SyncIt', 'Transaction'

COMMIT TRAN
于 2013-09-18T16:31:03.830 回答
0

我只想IDENTITY在每个表上放置一个字段,并让相应的条目与相应的 discountCode 相匹配 - 即,如果您预先有一千个 discountCodes,您在 discountCodes 表中的标识列的范围为 1 到 1000。这将匹配您的第一个 1 到1000 个条目。如果您获得超过 1000 个条目,只需为每个额外条目添加一个 discountCode。

这样,SQL Server 就会为您处理所有有问题的“获取序列中的下一个数字”逻辑。

于 2013-09-18T16:00:22.520 回答
0
WITH    e AS
        (
        SELECT  *,
                ROW_NUMBER() OVER (ORDER BY id) rn
        FROM    entries ei
        WHERE   NOT EXISTS
                (
                SELECT  NULL
                FROM    discountCodes dci
                WHERE   dci.entryId = ei.id
                )
        ),
        dc AS
        (
        SELECT  *,
                ROW_NUMBER() OVER (ORDER BY id) rn
        FROM    discountCodes
        WHERE   entryId IS NULL
        )
UPDATE  dc
SET     dc.entryId = e.id
FROM    e
JOIN    dc
ON      dc.rn = e.rn
于 2013-09-18T15:56:14.273 回答