2016-01-17 44 views
1

概述如何處理使用Yii2和MySQL事務的併發問題?

考慮以下細節:

  1. 我們有一個名爲user表。它是一個名爲wallet的列。
  2. 我們有一個名爲walletAction的表格。我們在用戶正在執行的每個錢包操作中插入一個新條目。這個表的作用就像數據庫中的某種日誌,並進行了一些計算。
  3. 我們有一個CRON命令,每N分鐘更新一次。每個CRON操作都通過使用獨立API獲取一些數據,並「插入」一個新的walletAction條目。在這段時間,它更新了userwallet的價值。
  4. A user可以從我們的網站上購買東西。當user點擊購買按鈕時,我們插入新的walletAction條目並更改userwallet欄。

問題

我恐怕CRON更新user行動時,他們點擊購買按鈕將在完全相同的時間發生引起了walletAction表中的條目有錯誤的計算。

我需要某種'鎖'的CRON更新執行或沿着這些線的東西。

問題

  1. 我應該害怕的這種情況呢?
  2. 我該如何避免這個問題?
  3. 我可以通過使用MySQL事務避免這種麻煩嗎?
  4. 應該使用什麼隔離級別,在哪種情況下應該使用它? (在cron命令或user的作用,當他們點擊購買按鈕?)
+0

你似乎對這個詞語不知所措;你擔心有**併發**問題。 – Keale

+1

[可能可以幫助](http://stackoverflow.com/questions/1195858/how-to-deal-with-concurrent-updates-in-databases) – Keale

回答

0

看來,我們沒有併發上php如在GOJava。你可以實現一些技術手段,但是他們幾乎都給你帶來了新的問題:)。爲了解決你的問題,我建議你使用optimistic lock。欲瞭解更多信息,你可以看到http://www.yiiframework.com/doc-2.0/guide-db-active-record.html#optimistic-locks

+0

我不會幫忙,因爲據我所知只在beforeSave之前鎖定,直到保存後。因此,如果我需要更改多個表(條目),這將是一個問題,因爲我需要全部鎖定它們,而不僅僅是「更新時刻的一個」。所以它不能幫助我。 – user1954544

0

是的,在這種情況下,我會建議使用trasactions與最強的隔離級別yii\db\Transaction::SERIALIZABLE。 這個級別應該防止「幻影讀取」和「不可重複讀取」。

此外,我建議始終在執行多個相關更改時使用事務,因爲它有助於保持數據庫一致性。 這可以防止在成功將新行插入walletAction之後,但在更新user.wallet之前得到一些PHP異常時的問題。