您的位置:首页技术文章
文章详情页

php - 数据库与逻辑应用分离的情况下怎么保证信息同步,或者叫安全

【字号: 日期:2022-06-13 16:04:13浏览:26作者:猪猪

问题描述

我不太明白这个词怎么表达

是这样的,现在有一台服务器运行数据库(server),另外一台运行php程序(client),浏览器(Browser)访问client,然后client逻辑判断后通过http协议对server中的数据库进行CURD操作

有个问题就是,如果Browser的用户操作过快,而server和client之间http请求太慢的话,就会导致client上获取的数据更新不及时,导致一些错误。。

栗子:一个用户只能买一个商品,用户点击之后,client先读取server的数据,判断是否已经购买,没有购买的话进行写入操作,然后购买完成,但是如果用户连着点击两次购买,两次操作一次进入client,然后由于client和server之间网速或者其他一些问题,写入操作没有及时完成造成两次购买操作的判断为此用户未购买,于是会有两次写入server数据库的操作,就会造成错误。。

这个问题属于什么?应该怎么解决?

问题解答

回答1:

用内存数据库或者NOSQL数据库来跟客户端交互,然后内存数据库跟MYSQL这类关系数据库“同步”。

如果客户端某些操作需要数据库查询来判断,这个时候如果是高并发的情况很容易就产生错误了。以前就经历过,比如用户注册判断是否有重名的,理论上是先查询数据库是否有该用户名存在然后插入,然而实际运营中这个逻辑竟然被打破了,发现了重名用户。

所以把核心的数据放到关系数据库,对速度有要求的使用内存数据库。适当的使用缓存以减小重复的查询。

回答2:

一般的解决方案是服务器先提供 token,有 token 才能成功操作,用完就会被标记过期。这样既可以保证不会重复操作,还可以做限流等功能。

而你的问有些不对题。如果是数据库与业务服务器之间通信的安全性,可以使用 SSL 协议。

还有一种做法是采用一致性哈希算出业务 id,不用自增 id。这样就可以保证很多操作幂等,有兴趣可以试试看。

回答3:

谢邀,你的栗子客户端做判断即可

回答4:

分配token之类的当然是非常好的解决方案。不过在实际应用中我觉得下面这种方案更加简洁高效:

前台js里面处理下,点击【购买】按钮后弹出全屏遮罩,阻止用户点击第二次,当后台成功后再把遮罩干掉。此外也可以使用标志位的方式,或者使用经典的debounce/throttle算法。

后台在购买流程中也判断下,短时间内(比如10秒内)的重复购买的时候直接返回“请不要重复操作”的错误。数据库方面可以考虑使用事务并把事务的隔离级别提高,或者使用锁。

一般前台js里面处理下后,很多问题都能避免了。除非有恶意用户。

回答5:

加并发锁,可以使用redis,memcached等,当一条请求完成后再释放锁

// 操作的原子性,如该key在有效时间30秒被设置过返回0,一般请求超时为30秒$redis->set($lock_key, 1, array('NX', 'EX'=>’30’));回答6:

从上面看你有两台服务器,一台运行php的server,另外一台db的server。然而你两台server之间的通讯为什么要使用http协议呢?而不是走mysql(假设你用的是mysql)默认的连接协议了?也就是说你应该在php中直接连到你server的数据库,然后操作DB。

对于你例子中提到的连续插入问题,可以通过表结构设计来完成,可以给字段添加唯一索引UNIQUE。另外还有一些其它方法,个人比较推荐唯一索引做法