我不太明白这个词怎么表达
是这样的,现在有一台服务器运行数据库(server
),另外一台运行php程序(client
),浏览器(Browser
)访问client
,然后client
逻辑判断后通过http
协议对server
中的数据库进行CURD
操作
有个问题就是,如果Browser
的用户操作过快,而server
和client
之间http请求太慢的话,就会导致client
上获取的数据更新不及时,导致一些错误。。
栗子:一个用户只能买一个商品,用户点击之后,client
先读取server
的数据,判断是否已经购买,没有购买的话进行写入操作,然后购买完成,但是如果用户连着点击两次购买,两次操作一次进入client
,然后由于client
和server
之间网速或者其他一些问题,写入操作没有及时完成,造成两次购买操作的判断为此用户未购买,于是会有两次写入server
数据库的操作,就会造成错误。。
这个问题属于什么?应该怎么解决?
用内存数据库或者NOSQL数据库来跟客户端交互,然后内存数据库跟MYSQL这类关系数据库“同步”。
如果客户端某些操作需要数据库查询来判断,这个时候如果是高并发的情况很容易就产生错误了。以前就经历过,比如用户注册判断是否有重名的,理论上是先查询数据库是否有该用户名存在然后插入,然而实际运营中这个逻辑竟然被打破了,发现了重名用户。
所以把核心的数据放到关系数据库,对速度有要求的使用内存数据库。适当的使用缓存以减小重复的查询。
一般的解决方案是服务器先提供 token,有 token 才能成功操作,用完就会被标记过期。这样既可以保证不会重复操作,还可以做限流等功能。
而你的问有些不对题。如果是数据库与业务服务器之间通信的安全性,可以使用 SSL 协议。
还有一种做法是采用一致性哈希算出业务 id,不用自增 id。这样就可以保证很多操作幂等,有兴趣可以试试看。
谢邀,你的栗子客户端做判断即可
分配token之类的当然是非常好的解决方案。不过在实际应用中我觉得下面这种方案更加简洁高效:
前台js里面处理下,点击【购买】按钮后弹出全屏遮罩,阻止用户点击第二次,当后台成功后再把遮罩干掉。此外也可以使用标志位的方式,或者使用经典的debounce/throttle算法。
后台在购买流程中也判断下,短时间内(比如10秒内)的重复购买的时候直接返回“请不要重复操作”的错误。数据库方面可以考虑使用事务并把事务的隔离级别提高,或者使用锁。
一般前台js里面处理下后,很多问题都能避免了。除非有恶意用户。
加并发锁,可以使用redis,memcached等,当一条请求完成后再释放锁
从上面看你有两台服务器,一台运行php的server,另外一台db的server。然而你两台server之间的通讯为什么要使用http协议呢?而不是走mysql(假设你用的是mysql)默认的连接协议了?也就是说你应该在php中直接连到你server的数据库,然后操作DB。
对于你例子中提到的连续插入问题,可以通过表结构设计来完成,可以给字段添加唯一索引UNIQUE。另外还有一些其它方法,个人比较推荐唯一索引做法