我用webman做的項(xiàng)目,如果遇到高并發(fā),會造成數(shù)據(jù)庫數(shù)據(jù)錯(cuò)亂嗎?
我的項(xiàng)目是一款問卷,每當(dāng)用戶提交問卷,數(shù)據(jù)庫某個(gè)字段會在尾部追加json數(shù)據(jù)
:如果B用戶刪除他的提交,A用戶正在編輯【A的提交】這個(gè)json數(shù)據(jù)【此時(shí)也包含B的提交】,然后他們同時(shí)發(fā)起請求,那么數(shù)據(jù)庫數(shù)據(jù)會錯(cuò)亂嗎?
疑問:B刪除了他的提交,結(jié)果A編輯時(shí)傳過去的數(shù)據(jù)也包含B,或出現(xiàn)B刪除失敗的情況嗎?(本來B更新后刪除成功,結(jié)果A攜帶B數(shù)據(jù),更新后,又加上了)
上述都是通過操作數(shù)組,然后轉(zhuǎn)json存數(shù)據(jù)庫的,每當(dāng)用戶提交問卷,就會在尾部array_push。然后編輯,刪除就是操作這個(gè)大數(shù)組
這個(gè)是數(shù)據(jù)庫層面的問題,跟框架沒關(guān)系
就是這里, 一直想不通,多個(gè)用戶操作一個(gè)大數(shù)組(增加,刪除,修改),然后一起發(fā)起請求,這個(gè)數(shù)組會不會亂?你覆蓋我的,我覆蓋你的
類似于秒殺,可以將請求排隊(duì)處理,即使并發(fā)來了多個(gè)請求,也放進(jìn)隊(duì)列,然后消費(fèi)隊(duì)列,一個(gè)一個(gè)處理
哥說的有道理,我想我設(shè)計(jì)有點(diǎn)不對,我想單表查詢更快,不過業(yè)務(wù)平均幾十人參加,每人還會隨機(jī)分發(fā)不同線路(1/10),兩人同時(shí)概率在一條線路并且同一時(shí)間更新的可能性很低
可以這樣:修改前馬上把修改id存入redis,設(shè)置一個(gè)狀態(tài)(他人不能操作),業(yè)務(wù)執(zhí)行完,狀態(tài)正常(他人可以操作)
這兩種鎖,我該使用哪個(gè)鎖?
Db::table('wj_options')
->where('id', $randOptinsId)
->??? //用哪個(gè)鎖?
->update($updateArr);
如果update在鎖的狀態(tài)時(shí),其他用戶來更新,返回false吧?
建議分表處理,為什么一張問卷表里把答案也存進(jìn)去?
“我想單表更快,省下鏈表?!?--數(shù)據(jù)量大的時(shí)候,并不見得單表能更快,而且對答案的分組分頁你怎么做?如果需要查詢呢?
“php不是單線程嗎?一次處理一個(gè)”---PHP是單線程,但可以多進(jìn)程,比方傳統(tǒng)的php-fpm,啟動一個(gè)會創(chuàng)建幾個(gè)進(jìn)程監(jiān)聽。
所以,分表后不存在你的疑慮,建議分表處理。
另外如果擔(dān)心mysql扛不住高并發(fā)的寫入,可以通過INSERT DELAYED或隊(duì)列等的方式,先把要寫入的內(nèi)容存內(nèi)存,再去寫入。
擔(dān)心數(shù)據(jù)丟失的話就走redis隊(duì)列或RabbitMQ隊(duì)列,它們不會成為你的瓶頸;
前端也做做手腳,提交的時(shí)候適當(dāng)增加隨機(jī)延遲參數(shù),比如隨機(jī)100~800毫秒,對用戶感知不高,確能有效削峰。
謝謝哥, 項(xiàng)目沒法改了, 只能操作大數(shù)組了,我的方案是:A操作時(shí),把A的uid和編輯id存到redis,當(dāng)A操作完了,就刪除redis,操作中如果B來操作就查詢r(jià)edis發(fā)現(xiàn)A,此時(shí)就提示B【太火爆,稍候再試】。 哥我說的這個(gè)方案可以嗎?