2011-08-28 51 views
2

我是db編程的新手。 我到處讀到,如果我遇到問題,我可以使用trasactions來回滾我的操作。使用MYSQL transcations,基本問題

我想知道有關事務:

  1. 沒有一個交易「鎖定」的分貝?
  2. 如果發生鎖定,其他用戶訪問db會發生什麼情況?他們可能會收到錯誤消息嗎?我應該以編程方式檢查這樣的錯誤,然後再試一次嗎?

是否有事情要做,使我的數據庫準備交易?比如將autocommit設置爲關閉?還有別的事嗎 ? 使用交易有缺點嗎?這對我來說似乎都很好。

在此先感謝!

回答

2

整個數據庫從不鎖定,這將是非常低效的。 而是,MySQL(取決於存儲引擎)鎖定記錄,並在某些情況下鎖定整個表格。

您需要確保存儲引擎是InnoDB,否則交易不可能。 自動提交功能僅存在於連接客戶端中,每次更改數據庫時都會發出提交。

事務會導致開銷並可能導致重大的性能問題。如果您嘗試以一次又一次的方式事務性地寫入同一條記錄(假設您的主頁上有一個計數器),那麼它會鎖定該記錄,並且會阻止很多寫入。

如果你需要在你的數據庫提供的一致性,才應使用交易,即一串記錄在一起應該寫在1路走,或者根本沒有。

1
  1. 簡單的答案是肯定的。
  2. 正在等待的查詢將一直等到表未被鎖定後再執行。

您應該知道,根據您正在使用的數據庫引擎(默認情況下爲MyISAM),鎖定是按表進行的。有像InnoDB這樣的不同引擎可以實現行鎖定。

此外,即使它們全部位於不同的表上,也可以同時執行多個查詢。如果你超過這個數字,你也會收到一個鎖。您可以在phpmyadmin中查看您收到的鎖的數量,以確定數據庫處理中是否存在問題。

關於事務處理:有時您希望使用部分信息更新數據庫。這真的取決於你的使用。

+0

MyISAM不支持事務,表級和行級鎖不完全是事務鎖,它們是在存儲引擎中實現的鎖定機制。 –

1

答案1.不可以。它根據查詢的性質鎖定部分表或完整表。這些locak可以被讀取或寫入鎖定。回答2.如果用戶想要鎖定另一個用戶有寫入鎖定的表格的一部分,則用戶被保持到鎖定變爲空閒狀態。如果另一個用戶具有讀鎖定並且用戶想要寫鎖定,則用戶被保持直到鎖定變爲空閒。您需要閱讀有關死鎖的信息。

希望有所幫助。

2
  1. 號他們allow queries to lock specific portions of the database,並允許數據庫引擎來呈現甚至正在更新表中的數據到其他客戶端的統一視圖。

  2. 他們看到的數據是在發生相關查詢之前的數據,並且可能會阻止他們寫入表中。

並非所有的表引擎支持事務,所以你需要使用一個沒有(例如InnoDB),和交易做需要大量的時間來處理非零量。

+0

他們看到的實際上取決於隔離級別,但作爲一種簡化,您的答案是完全正確的。 +1 –

1

因爲我們正在談論的MySQL和交易,是全部的答案是關於InnoDB的,雖然大部分是適用於任何存儲引擎,支持事務。

在交易鎖定取決於存儲引擎和transaction isolation level。 MySQL/InnoDB使用行版本化來實現事務處理,並且降低了所有隔離級別使用的鎖的數量,除了可序列化之外。 MySQL中的默認隔離級別是可重複讀取的。

通常更新使用寫入鎖,這意味着另一個事務不能更新同一行,但可以讀取它。如果你嘗試訪問一個被鎖定的行,MySQL將等待,直到達到鎖定等待超時,然後將終止該查詢,通知你達到了鎖定等待超時。通常這不應該發生。最危險的部分然而使用事務,推出dead-locks - 當transaction A更新record1並嘗試更新record2,這是由transaction B鎖定 - transaction B已經更新record2並嘗試更新record1,但record1A鎖定,這樣既等待彼此。

一般建議是儘可能保持您的事務處於儘可能小的狀態,並儘早鎖定要更新的行,以防止死鎖(您可以使用select ...來更新)。

很多信息可以在MySQL documentation和MySQL認證指南中找到。