我正在使用SQL Server 2012.
我有用于存储用户的表。允许的最大用户数为100万。我有一个我正在注册用户的sproc。当我插入时,我想确保users表中的总行数不超过100万。我更愿意使用一种允许最大并发的方法。
我相信我可以使用具有SERIALIZABLE的ISOLATION LEVEL的事务,然后首先计算行数并在总计数小于1百万时插入。我的理解是SERIALIZABLE是非常严格的,并且随着并发性的增加会导致性能下降。
IF(SELECT COUNT(*) FROM Users) < 100000
BEGIN
INSERT INTO Users VALUES (@Name, @Email, @Password)
END
如何以原子方式执行此操作以确保总行数少于100万,但同时我执行最小锁定以防止阻止其他事务?
针对这种情况的任何解决方案/最佳做法?
答案 0 :(得分:6)
您可以创建SELECT
来检查用户数量并检索新用户的数据,并使用该选项插入表格中:
INSERT INTO users (
name, email, [password]
)
SELECT
'newUser' AS name
, 'email@example.com' AS email
, 'fsfsfs' AS [password]
FROM
users
HAVING
COUNT(*) < 100000;
当数据库中的用户少于100000时,SELECT
语句将返回一行,当有100000个或更多用户时,将返回0记录。
整个语句(INSERT..SELECT
)在每种情况下都有效,但当SELECT
部分返回0行时,INSERT
将不会插入任何内容。
使用SERIALIZABLE
事务级别,可以保证concurent写入不会相互干扰。 COUNT(*)使用最有效的索引/键来计算行数,这意味着锁定时间将是最小的。
由于整个操作在一个语句中完成,因此可以防止在执行SELECT
和INSERT
之间插入