一个用户多条记录,以最后记录产生新的余额记录

来源:互联网 发布:张剑黄皮书知乎 编辑:程序博客网 时间:2024/06/15 06:25
原贴: 点击打开链接
-- 测试表及测试数据开始USE tempdbGOIF OBJECT_ID('t') IS NOT NULL DROP TABLE tCREATE TABLE t(id INT IDENTITY(1,1) PRIMARY KEY ,userId INT NOT NULL,consume INT NOT NULL,balance INT NOT NULL)--第一条记录视为交费,交费直接插入就好,不需要任何逻辑INSERT INTO t(userId,consume,balance) VALUES(120,9,1000)-- 测试表及测试数据结束----- 插入消费记录 BEGIN ------- 用 SqlQueryStress 工具测试 50线程,每线程循环10次DECLARE @userId INT,@consume INTSET @userId=120SET @consume=1 INSERT INTO t(userId,consume,balance)SELECT @userId,@consume,balance-@consumeFROM t WHERE userId=@userIdAND id = (SELECT MAX(id) FROM t WITH(TABLOCK) WHERE userId=@userId)--注:上面With 后面只能加 TABLOCK ,其它锁都会有问题无法通过后面的验证----- 插入消费记录 END ---------- 验证开始 -------验证是否有操作失误的记录(消费了余额不可能不变化)SELECT * FROM t a WHERE EXISTS(SELECT * FROM t b WHERE a.id!=b.id AND a.balance=b.balance)--无记录SELECT TOP 1 * FROM t ORDER BY id DESC/*iduserIdconsumebalance501  120  1       500*/----- 验证结束 -----


后记:

TABLOCK的效率是最低的,不过按楼主的需求,只有表锁才能满足要求了。

建议用户表中增加一个字段:余额,每次更新用户表, 只需要锁定一行, 而且根本不需要写显式的锁和事务。 效率高很多。

更新完用户表, 往现在的这个表里面插入一条记录即可。


附:锁的相关知识:点击打开链接


原创粉丝点击