仅当总数小于阈值时,才将行插入到SQL Server表中
技术问答
198 人阅读
|
0 人回复
|
2023-09-14
|
我正在使用SQL Server 2012。
0 u5 m- X0 {4 T+ Q$ Z/ {; f我有用于存储用户的表。允许的最大用户数为100万。我有一个要在其中注册用户的程序。当我插入时,我想确保用户表中的总行数不会超过100万。我宁愿使用允许最大并发性的方法。
K* Y' O" R- I7 w我相信我可以使用ISOLATION
% l& m: X7 W( X6 m+ T( wLEVEL为SERIALIZABLE的事务,然后首先计算行数,如果总计数少于100万,则插入行。我的理解是SERIALIZABLE的限制非常严格,并且会随着并发性的增加而导致性能下降。
3 ]1 n- R( G5 SIF(SELECT COUNT(*) FROM Users) 如何自动执行此操作,以确保总行数小于100万,但是同时我进行了最小限度的锁定以防止阻止其他事务?
: X+ C5 M+ t5 A# H( p' o有什么解决方案/最佳做法可以解决这种情况吗?
1 i S7 {. K' H6 Y! L $ J& F5 r5 c4 [# ]0 C- c
解决方案: b2 L/ J; @5 q
& x4 x( b1 }6 H" Y7 l* A$ K% a( l
+ U, d9 l. q) L/ |% v% q% r
6 s* ]2 z" g g6 M 您可以创建一个SELECT来检查用户数并检索新用户的数据,然后使用该选择将其插入表中:7 s/ `. a: G- D
INSERT INTO users (
* g4 u: }( U& X$ o4 j: D name, email, [password]) a, l- r" p3 d
)
) [; \0 B/ C; W4 j3 F0 z& dSELECT
# s {% n5 g' @- A) A$ |. y! m4 t 'newUser' AS name! z3 o3 U2 ?. w* |
, 'email@example.com' AS email
5 {0 L+ B% x# u , 'fsfsfs' AS [password]
0 ?+ K, p/ h: zFROM
4 f* b0 x% Y1 Z: a! v; z) Q) ` users
0 e7 I3 X! O. c+ @6 qHAVING9 Q$ E. _/ l/ u! l. A+ k; Q
COUNT(*) SELECT当数据库中的用户数少于100000时,该语句将返回一行;如果用户数为100000或更多,则该语句将返回0记录。, b7 T k0 m, l5 g E' q+ L A
整个语句(INSERT..SELECT)在每种情况下均有效,但是当该SELECT部分返回0行时,INSERT将不会插入任何内容。* ]1 E' v, G" J% g P
通过SERIALIZABLE事务级别,可以确保并发写入不会互相干扰。COUNT(*)使用最有效的索引/键对行进行计数,这意味着锁定时间将最短。
/ F% l% K# W1 y. W由于整个动作是在一个语句中完成的,因此可以防止在SELECT和的执行之间插入INSERT
J0 Z6 l) w& m m C6 xSQL Fiddle演示 |
|
|
|
|
|