数据更新的问题

幽夜莫知途 2021-04-25 04:02:53
现在有一个场景,有这样一个注册方法 先执行查询语句查询有没有一条user的数据没有就往里面insert,但是现在同一时刻有两个请求也就是一个时刻会执行两次这个注册方法,这也就导致第一次查询是没有user紧跟着第二次也是没有user的所以会执行两次insert最后数据库会有两个这样的user,这个问题怎么解决,求教
...全文
1726 点赞 收藏 27
写回复
27 条回复
xiaoxiangqing 04月30日
用redis锁是简单的
回复 点赞
ghr65e4hh 04月29日
都是大牛,膜拜
回复 点赞
heyingss 04月29日
学习。。。。。。
回复 点赞
xiaoxiangqing 04月29日
用redis锁实现就比较简单
回复 点赞
luj_1768 04月28日
对于运行数据库,这种时序有关的不一致性很难办,通常需要考虑运行环境、客户数量、服务策略,一般可以采取缓冲延迟批量更新、在更新批量中做冲突判断的策略(缓冲前是预判断),这样系统锁比较容易操作。
回复 点赞
幽夜莫知途 04月28日
引用 16 楼 足球中国 的回复:
幂等性问题。 user用用户输入的用户名作为唯一,重复是插入不进去的。id自增作为辅助redis使用 https://cn.bing.com/search?q=%E5%B9%82%E7%AD%89%E6%80%A7&cvid=d3e90e43b9ee4ebb865341b551893aa3&aqs=edge..69i57j0l6.5845j0j1&pglt=129&FORM=ANNTA1&PC=U531
引用 16 楼 足球中国 的回复:
幂等性问题。 user用用户输入的用户名作为唯一,重复是插入不进去的。id自增作为辅助redis使用 https://cn.bing.com/search?q=%E5%B9%82%E7%AD%89%E6%80%A7&cvid=d3e90e43b9ee4ebb865341b551893aa3&aqs=edge..69i57j0l6.5845j0j1&pglt=129&FORM=ANNTA1&PC=U531
引用 16 楼 足球中国 的回复:
幂等性问题。 user用用户输入的用户名作为唯一,重复是插入不进去的。id自增作为辅助redis使用 https://cn.bing.com/search?q=%E5%B9%82%E7%AD%89%E6%80%A7&cvid=d3e90e43b9ee4ebb865341b551893aa3&aqs=edge..69i57j0l6.5845j0j1&pglt=129&FORM=ANNTA1&PC=U531
引用 16 楼 足球中国 的回复:
幂等性问题。 user用用户输入的用户名作为唯一,重复是插入不进去的。id自增作为辅助redis使用 https://cn.bing.com/search?q=%E5%B9%82%E7%AD%89%E6%80%A7&cvid=d3e90e43b9ee4ebb865341b551893aa3&aqs=edge..69i57j0l6.5845j0j1&pglt=129&FORM=ANNTA1&PC=U531
专业
回复 点赞
movsd 04月28日
unique index
回复 点赞
幽夜莫知途 04月28日
先不结贴,再看看,欢迎讨论
回复 点赞
hzjjhzx 04月28日
学习。。。。。
回复 点赞
YBcsdn1996 04月28日
简单粗暴的方法是 数据库user 设置为主键 用主键约束 如果不能设置主键 那么就用事务锁 个人觉得主键来得实在 这种并发式的插入 就算原表各种原因不能设置主键 那么也可以使用一张中间表 设为主键
回复 点赞
数字UI 04月28日
方法一:使用 lock 锁定逻辑块依次执行。 lock (this) { ///注册查询逻辑 ///写库逻辑 } 方法二:数据库表中指定 某字段为 唯一索引来避免重复插入。
回复 点赞
足球中国 04月27日
幂等性问题。 user用用户输入的用户名作为唯一,重复是插入不进去的。id自增作为辅助redis使用 https://cn.bing.com/search?q=%E5%B9%82%E7%AD%89%E6%80%A7&cvid=d3e90e43b9ee4ebb865341b551893aa3&aqs=edge..69i57j0l6.5845j0j1&pglt=129&FORM=ANNTA1&PC=U531
回复 点赞
幽夜莫知途 04月27日
引用 12 楼 datafansbj 的回复:
需要使用事务机制保证数据的一致性,只判断是否存在是不够的。
是锁代码块吗?
回复 点赞
datafansbj 04月27日
需要使用事务机制保证数据的一致性,只判断是否存在是不够的。
回复 点赞
泡泡鱼_ 04月27日
引用 5 楼 xuzuning 的回复:
数据表的自增主键 的唯一性,是由数据库系统保证的 无论怎么并发都是唯一的 所以先插入,然后根据自增键修改是最稳妥的方案
引用 12 楼 datafansbj 的回复:
需要使用事务机制保证数据的一致性,只判断是否存在是不够的。
这两位说的都可行呀。 假定你有个字段ID,自增主键,你不管怎么并发,插入库以后是不是都必定有个不同的ID?你插入后直接获取本次插入后返回的这个ID,然后你可以校验了。id<当前插入生成的ID and user=当前插入的use。如果找到,删除,返回错误,否则返回正确。结合12楼的朋友说的,你可以放在事务中,判断重复后,回滚,返回错误代码 你可以试下
回复 点赞
weixin_42066565 04月27日
回帖test
回复 点赞
幽夜莫知途 04月26日
引用 7 楼 qq_30335331的回复:
[quote=引用 4 楼 幽夜莫知途 的回复:][quote=引用 2 楼 qq_30335331 的回复:]不管你怎么并发 处理数据的只有一个 不存在同时两个这种说法 直接简单粗暴的办法就是 改下插入语句改成 if exits(查询) begin insert end
我的逻辑也是这样,现在的执行顺序是 1:exits() 第一次前端请求 2: exits() 紧跟第二次请求 3: insert 第一次的 4 insert 第二次的[/quote] DROP TABLE test CREATE TABLE test ( test varchar(10) ) IF NOT EXISTS(SELECT * FROM test) BEGIN INSERT INTO test VALUES('1') END IF NOT EXISTS(SELECT * FROM test) BEGIN INSERT INTO test VALUES('2') END SELECT * FROM test 就算这个代码一起执行 数据库中也是始终为1 2不可能插得进去[/quote] 并没有写sql控制,是用代码写的判断
回复 点赞
qq_30335331 04月26日
引用 4 楼 幽夜莫知途 的回复:
[quote=引用 2 楼 qq_30335331 的回复:]不管你怎么并发 处理数据的只有一个 不存在同时两个这种说法 直接简单粗暴的办法就是 改下插入语句改成 if exits(查询) begin insert end
我的逻辑也是这样,现在的执行顺序是 1:exits() 第一次前端请求 2: exits() 紧跟第二次请求 3: insert 第一次的 4 insert 第二次的[/quote] DROP TABLE test CREATE TABLE test ( test varchar(10) ) IF NOT EXISTS(SELECT * FROM test) BEGIN INSERT INTO test VALUES('1') END IF NOT EXISTS(SELECT * FROM test) BEGIN INSERT INTO test VALUES('2') END SELECT * FROM test 就算这个代码一起执行 数据库中也是始终为1 2不可能插得进去
回复 点赞
姎楹 04月26日
就算第一次insert没有提交,同一个事务第二次查是否存在,应该也是存在的
回复 点赞
幽夜莫知途 04月26日
引用 9 楼 爱喝茶的助手的回复:
直接在执行sql语句insert前做个EXISTS判断呗
我就是这样的,你是不是认为,这段代码块是第一次完整执行一遍第二次又完整执行一遍?我这里的情况是:由于前端极短时间内发送了两个请求,所以目前执行情况是 第一次请求执行第一行,然后第二次请求执行第一行 然后才是下一行代码。
回复 点赞
发动态
发帖子
C#
创建于2007-09-28

8.5w+

社区成员

64.0w+

社区内容

.NET技术 C#
社区公告
暂无公告