1. 程式人生 > >Mysql主從庫讀寫與事務

Mysql主從庫讀寫與事務

通常任務系統會選擇生產者-消費者模型,中間有一個佇列用於記錄任務,例如使用 redis 的佇列結構。同時任務扭轉和執行狀態資訊落盤儲存,例如 Mysql 的一張表。此時會有有兩個模組同時讀寫 Mysql 的同一條資料。

通常說來 Mysql 的配置是一主兩從,分別在3臺機器上。寫操作和事務操作落在主庫,讀操作大都落在從庫。以上面的模型為例子:
1、生產者產生了一個任務,加入 redis 中,同時在 Mysql 中寫入一條任務初始化資料;
2、消費者從 redis 中取出一條資料,緊接著從 Mysql 中取出對應對應任務記錄,更新相關資訊;

如果生產者的生產和消費者的消費之間間隔很小,那麼很有可能會因為主從同步延遲的問題,導致消費者在 Mysql 中取不到任務記錄。

一般來說,解決辦法是消費者的這次讀操作加上事務,那麼會落到主庫。此時一定會讀取到任務記錄,保證業務上的一致性。

我在使用 java spring 系做這些的時候,還遇到一個點。為了提高效能,我不會對整個業務方法加上 @Transaction 事務註解,這樣可能會導致事務太大。我一般把相關 sql 語句抽取出來,就地單獨成一個方法,然後在這個方法上加上 @Transaction 事務註解。

然而這樣做不對。不是說想法不對,而是忽略了 spring 的機制。如果就地成一個方法,那麼這個方法會在當前類的某個方法中呼叫。此時,會因為 AOP 的機制導致事務壓根兒沒生效。AOP 的機制是對介面代理。而方法內在呼叫,已經不會經過這一層封裝,所以此時的事務註解沒起作用。比較簡單的解決方式是新建一個類,作為這類 sql 的組合封裝。然後在這些類方法上加上事務註解。