不會,這里的原子性不要從php的角度看,應該從redis的角度看,同一個redis節(jié)點對并發(fā)的請求都是序列化處理的,所以單操作不存在你擔心的并發(fā)問題,但如果是read write的形式到哪里都不行了,切記。
創(chuàng)新互聯(lián)建站專注為客戶提供全方位的互聯(lián)網(wǎng)綜合服務,包含不限于成都網(wǎng)站設計、網(wǎng)站制作、外貿(mào)營銷網(wǎng)站建設、中寧網(wǎng)絡推廣、微信平臺小程序開發(fā)、中寧網(wǎng)絡營銷、中寧企業(yè)策劃、中寧品牌公關、搜索引擎seo、人物專訪、企業(yè)宣傳片、企業(yè)代運營等,從售前售中售后,我們都將竭誠為您服務,您的肯定,是我們最大的嘉獎;創(chuàng)新互聯(lián)建站為所有大學生創(chuàng)業(yè)者提供中寧建站搭建服務,24小時服務熱線:18982081108,官方網(wǎng)址:www.cdcxhl.com
有人問到read write是啥,其實就是并發(fā)的一個經(jīng)典問題,代碼如下
$v = $redisClient-get('v');
$v ++;
$redisClient-set('v', $v);
就是先讀取數(shù)據(jù),再修改數(shù)據(jù),在寫回修改,這里是希望每次訪問都遞增v的值,但在并發(fā)情況下,兩個進程都讀取到了一樣的初始值,比如3,然后都加1變?yōu)?,最后把4寫回Redis,這種情況就會統(tǒng)計數(shù)據(jù)比實際的少。盡量都用Redis的原子操作就好,比如incr。
使用程序無法實現(xiàn)這種功能,因為無法保證事務的一致性,比如:A數(shù)據(jù)庫中的a表復制到B數(shù)據(jù)庫中的a表的過程中,A數(shù)據(jù)庫中的a表的一條記錄被刪除,這樣就無法實現(xiàn)數(shù)據(jù)的一致性!正確的做法是使用MySQL復制的功能!很簡單,只需要幾步配置即可!
php的在頁面載入時或調(diào)用session_start()時從數(shù)據(jù)源中讀取session數(shù)據(jù)到$_SESSION變量。
當頁面執(zhí)行完畢或調(diào)用session_write_close()時把$_SESSION變量寫入數(shù)據(jù)源。
php默認的session.save_handler=files,可以通過文件鎖來實現(xiàn)讀寫同步,保證session數(shù)據(jù)的一致性,不會產(chǎn)生問題。然而當使用sqlite作為session handler時,由于沒有同步機制,會產(chǎn)生bug。如下代碼:
test1.php
PHP code?
session_start();
$_SESSION['data1'] = 'data1';
sleep(10);
session_write_close();
test2.php
PHP code?
session_start();
$_SESSION['data2'] = 'data2';
session_write_close();
在同一瀏覽器進程里(保證使用相同的session_id),先訪問test1.php,再訪問test2.php,會發(fā)現(xiàn)data2根本沒有寫入sqlite數(shù)據(jù)庫中。session.save_handler=memcache還沒有測試,估計也有這個問題。如果采用默認的files handler會發(fā)現(xiàn)test2.php的請求會被掛起直至test1.php執(zhí)行完畢,這就是文件鎖同步機制造成的。
我想到了兩種解決方案:
1、實現(xiàn)互斥鎖,保證同一session_id訪問session數(shù)據(jù)是同步的,這樣會產(chǎn)生一個阻塞的問題(php默認的session實現(xiàn)也會有這個問題)。
2、寫入session數(shù)據(jù)時進行數(shù)據(jù)合并,不過這樣仍然不能完全保證數(shù)據(jù)一致性。