我的 python/wsgi Web 應用程式中的會話出現問題。 2 個 wsgi 守護程式中的每個執行緒都有一個不同的、持久的 mysqldb 連線。有時,在刪除舊會話並建立新會話後,某些連線仍然會在選擇中取得舊會話,這表示它們無法驗證會話並要求再次登入。
詳細資訊:會話儲存在本機 mysql 資料庫的 InnoDB 表中。驗證(透過 CAS)後,我刪除該使用者先前的任何會話,建立一個新會話(插入一行),提交事務,並使用 cookie 中的新會話 ID 重定向到最初請求的頁面。對於每個請求,都會根據資料庫中的會話檢查 cookie 中的會話 ID。
有時,重定向後在資料庫中找不到新建立的會話。相反,該使用者的舊會話仍然存在。 (我透過在每個請求開始時選擇並記錄所有會話來檢查這一點)。不知何故,我得到了緩存的結果。我嘗試使用 SQL_NO_CACHE 選擇會話,但沒有什麼區別。
為什麼我會得到快取結果?快取還可能在哪裡發生,如何停止它或刷新快取?基本上,為什麼其他連線無法看到新插入的資料?
P粉6968918712023-10-31 10:19:28
是的,看起來假設您只會執行一個事務,然後斷開連線。如果您有不同的需求,那麼您需要解決這個假設。正如 @a_horse_with_no_name 所提到的,您可以進行提交(儘管如果您實際上沒有更改數據,我會使用回滾)。或者您可以更改遊標上的隔離級別 - 來自 這個討論我用過這個:
dbcursor.execute("設定會話交易隔離等級讀取已提交")
或者,看起來您可以在連線上將自動提交設定為 true:
dbconn.autocommit(True)
不過,如果實際對連接進行更改,則不建議這樣做。
P粉5459565972023-10-31 09:25:48
MySQL 預設隔離等級“REPEATABLE READ”,這表示您不會看到交易啟動後所做的任何變更 - 即使這些(其他)變更已提交。
如果您在這些會話中發出 COMMIT 或 ROLLBACK,您應該會看到更改的資料(因為這將結束「正在進行的」交易)。
另一個選項是將這些會話的隔離等級變更為「READ COMMITTED」。也許還有一個選項可以更改預設級別,但您需要查看手冊。