首頁  >  問答  >  主體

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

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

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

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

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

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

迷茫迷茫2742 天前939

全部回覆(6)我來回復

  • 怪我咯

    怪我咯2017-04-17 16:50:34

    用記憶體資料庫或NOSQL資料庫來跟客戶端交互,然後記憶體資料庫跟MYSQL這類關係型資料庫「同步」。

    如果客戶端某些操作需要資料庫查詢來判斷,這個時候如果是高並發的情況很容易就產生錯誤了。以前就經歷過,例如用戶註冊判斷是否有重名的,理論上是先查詢資料庫是否有該用戶名存在然後插入,然而實際運營中這個邏輯竟然被打破了,發現了重名用戶。

    所以把核心的資料放到關聯式資料庫,對速度有要求的使用記憶體資料庫。適當的使用快取以減少重複的查詢。

    回覆
    0
  • ringa_lee

    ringa_lee2017-04-17 16:50:34

    一般的解決方案是伺服器先提供 token,有 token 才能成功操作,用完就會被標記過期。這樣既可以確保不會重複操作,還可以做限流等功能。

    而你的問有些不對題。如果是資料庫與業務伺服器之間通訊的安全性,可以使用 SSL 協定。

    還有一種做法是採用一致性哈希算出業務 id,不用自增 id。這樣就可以確保很多操作冪等,有興趣可以試試看。

    回覆
    0
  • 天蓬老师

    天蓬老师2017-04-17 16:50:34

    謝邀,你的栗子客戶端做判斷即可

    回覆
    0
  • ringa_lee

    ringa_lee2017-04-17 16:50:34

    分配token之類的當然是非常好的解決方案。不過在實際應用上我覺得下面這種方案比較簡潔有效率:

    1. 前台js裡面處理下,點選【購買】按鈕後彈出全螢幕遮罩,阻止使用者點擊第二次,當後台成功後再把遮罩幹掉。另外也可以使用標誌位的方式,或是使用經典的debounce/throttle演算法。

    2. 後台在購買流程中也判斷下,短時間內(例如10秒內)的重複購買的時候直接返回「請不要重複操作」的錯誤。資料庫方面可以考慮使用事務並將事務的隔離等級提高,或使用鎖。

    一般前台js裡面處理下後,很多問題都能避免了。除非有惡意使用者。

    回覆
    0
  • 伊谢尔伦

    伊谢尔伦2017-04-17 16:50:34

    加上並發鎖,可以使用redis,memcached等,當一條請求完成後再釋放鎖

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

    回覆
    0
  • 黄舟

    黄舟2017-04-17 16:50:34

    從上面看你有兩台伺服器,一台運行php的server,另一台db的server。然而你兩台server之間的通訊為什麼要使用http協定呢?而不是走mysql(假設你用的是mysql)預設的連線協定了?也就是說你應該在php中直接連到你server的資料庫,然後操作DB。

    對於你例子中提到的連續插入問題,可以透過表格結構設計來完成,可以為欄位新增唯一索引UNIQUE。另外還有一些其它方法,個人比較推薦唯一索引做法

    回覆
    0
  • 取消回覆