回答

收藏

仅当总数小于阈值时,才将行插入到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演示
分享到:
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则