MySQL 4.1.0 中文參考手冊 --- 6.7 MySQL 事務與鎖定命令 (轉)
MySQL Reference Manual for version 4.1.0-alpha.
6.7 MySQL 事務與鎖定命令
6.7.1 BEGIN/COMMIT/ROLLBACK
句法
預設的,MySQL 執行在 autocommit
。這就意味著,當你完一個時,MySQL 將立刻將更新到上。
如果你使用事務表 (例如 Inno
、BDB
),透過下面的命令,你可以設定 MySQL 為非 autocommit
模式:
SET AUTOCOMMIT=0
在此之後,你必須使用 COMMIT
來儲存你的更改到磁碟上,或者使用 ROLLBACK
,如果你希望忽略從你的事務開始所做的更改。
如果你希望為一系列語句從 AUTOCOMMIT
模式轉換,你可以使用 START TRANSACTION
或 BEGIN
或 BEGIN WORK
語句:
START TRANSACTION; @A:=SUM(salary) FROM table1 WHERE type=1; UPDATE table2 SET summmary=@A WHERE type=1; COMMIT;
START TRANSACTION
在 MySQL 4.0.11 中被加入;這是被推薦的開始一個特別(ad-hoc)事務的方式,因為這是 ANSI SQL 句法。
注意,如果你使用的是一個非事務安全表,更改會立刻被儲存,不受 autocommit
模式狀態的。
當你更新了一個非事務表後,如果你執行一個 ROLLBACK
,你將得到一個錯誤 (ER_WARNING_NOT_COMPLETE_ROLLBACK
) 作為一個警告。所有事務安全表將被恢復,但是非事務安全表將不會改變。
如果你使用 START TRANSACTION
或 SET AUTOCOMMIT=0
,你應該使用 MySQL 二進位制日誌做以代替老的更新日誌。事務處理被以一個大塊形式儲存在二進位制日誌中,在 COMMIT
上面,為了保護回滾的事務,而不是被儲存的。檢視章節 。如果您使用起動事務處理或集AUTOCOMMIT=0 ,您應該使用MySQL 二進位制日誌為備份代替更舊的更新日誌。 事務處理儲存在二進位制登入一大塊,做,保證, 滾的事務處理不儲存。 參見部分4 。9.4 二進位制日誌。
下列命令自動的結束一個事務 (就好像你在執行這個命令之前,做了一個 COMMIT
):
ALTER TABLE
BEGIN
CREATE INDEX
DROP DATABASE
DROP TABLE
RENAME TABLE
TRUNCATE
你可以使用 SET TRANSACTION ISOLATION LEVEL ...
改變事務的隔離級。檢視章節 。
6.7.2 LOCK TABLES/UNLOCK TABLES
句法
LOCK TABLES tbl_name [AS alias] {READ [LOCAL] | [LOW_PRIORITY] WRITE} [, tbl_name [AS alias] {READ [LOCAL] | [LOW_PRIORITY] WRITE} ...] ... UNLOCK TABLES
LOCK TABLES
為當前執行緒鎖定表。UNLOCK TABLES
釋放當前執行緒擁有的所有鎖定。當執行緒發出另一個 LOCK TABLES
,或當與的連線被關閉時,被當前執行緒鎖定的所有表將被自動地解鎖。
為了在 MySQL 4.0.2 使用 LOCK TABLES
,你必須擁有一個全域性的 LOCK TABLES
和一個在相關表上的 SELECT
許可權。在 MySQL 3.23 中,你對該表需要有 SELECT
、insert
、DELETE
和 UPDATE
許可權。
使用 LOCK TABLES
的主要原因是,仿效事務處理或在更新表時得到更快的速度。此後會有更詳細的描述。
如果一個執行緒在一個表上得到一個 READ
鎖,該執行緒 (和所有其它執行緒) 只能從表中讀取。如果一個執行緒在一個表上得到一個 WRITE
鎖,那麼只有擁有這個鎖的執行緒可以從表中讀取和寫表。其它的執行緒被阻塞。
READ LOCAL
和 READ
之間的不同就在於,當鎖被載入時,READ LOCAL
允許非衝突(non-conflicting) INSERT
語句執行。如果當你載入著鎖時從 MySQL 外部操作,這將仍不能被使用。
當你使用 LOCK TABLES
是地,你必須鎖定所有你將使用的表,並且必須使用與你的查詢中將使用的別名相同!如果你在一個查詢中多次使用一個表(用別名),你必須為每一個別名獲得一個鎖。
WRITE
鎖透過比 READ
鎖有更高的許可權,以確保更新被儘快地處理。這就意味著,如果一個執行緒獲得一個 READ
鎖,而同時另外一個執行緒請求一個 WRITE
鎖,併發的 READ
鎖請求將等待直到 WRITE
執行緒得到了鎖並釋放了它。你可以使用 LOW_PRIORITY WRITE
鎖,當該執行緒在等待 WRITE
鎖時,它將允許其它的執行緒獲得 READ
鎖。 你應該只使用 LOW_PRIORITY WRITE
鎖,如果你確信這將是最後一次,當沒有執行緒將擁有 READ
鎖。
LOCK TABLES
工作如下:
- 以內部定義的次序排序所有被鎖定的表 (從立場說,該次序是不明確的)。
- 如果一個表被以一個讀鎖和一個寫鎖鎖定,將寫鎖放在讀鎖之前。
- 一次只鎖定一個表,只到執行緒得到所有的鎖定。
這個方案是為了確保,表鎖定死鎖釋放。 對於這個模式你仍然有些其它事情需要知道:
如果你對一個表使用一個 LOW_PRIORITY WRITE
鎖定,這就意味著,MySQL 將等待這個鎖,直到沒有執行緒請求一個 READ
鎖。當執行緒得到了 WRITE
鎖,並等待獲得鎖定表列表中的下一個表的鎖定時,其它所有的執行緒將等待 WRITE
鎖被釋放。如果這在你的應用中會引起一個嚴重的問題,你應該考慮將你的某些錶轉換為事務安全表。
你可以使用 KILL
安全地殺死一個正在表鎖定的執行緒。檢視章節 。
注意,你不應該 鎖定你正在對其使用 INSERT DELAYED
的表。這是因為,在這種情況下,INSERT
是透過單獨的執行緒完成的。
通常,你不需要鎖定任何表,因為所有單 UPDATE
語句都是原子的;其它的執行緒無法干擾當前執行的 SQL 語句。當你無論如何希望鎖定表時,這裡有一些情況:
- 如果你在一束表上執行許多操作,鎖定你將要使用的表,這會更快一些。當然有不利的方面,其它執行緒將不能更新一個
READ
鎖的表,並且沒有其它執行緒要以讀取一個WRITE
鎖的表。在LOCK TABLES
下,某些事執行得更快一些的原因是,MySQL 將不會轉儲清除被鎖定表鍵高速緩衝,直到UNLOCK TABLES
被 (通常鍵高速緩衝在每個 SQL 語句後都會被轉儲清除)。這將加速在MyISAM
表上的插入、更新、刪除。 - 如果你在 MySQL 中正在使用一個不支援事務的儲存引擎,如果你希望能確保沒有其它的執行緒會出現在一個
SELECT
和 一個UPDATE
之間,你必須使用LOCK TABLES
。下面的示例顯示為了安全地執行,這裡需要LOCK TABLES
:mysql> LOCK TABLES trans READ, customer WRITE; mysql> SELECT SUM(value) FROM trans WHERE customer_id=some_id; mysql> UPDATE customer SET total_value=sum_from_previous_statement -> WHERE customer_id=some_id; mysql> UNLOCK TABLES;
不使用LOCK TABLES
,將可能發生在SELECT
和UPDATE
語句執行期間有另外一個執行緒可能在trans
表中插入一行新記錄。
透過使用遞增更新 (UPDATE customer SET value=value+new_value
) 或 LAST_INSERT_ID()
,你可以在很多情況下避免使用 LOCK TABLES
。
你也可以使用使用者級鎖定函式 GET_LOCK()
和 RELEASE_LOCK()
解決一些情況,這些鎖被儲存在伺服器上的一個雜湊表中,並以 pthread_mutex_lock()
和 pthread_mutex_unlock()
實現以獲得高速度。檢視章節 。
檢視章節 ,以獲取關於鎖定方案的更多資訊。
你可以使用 FLUSH TABLES WITH READ LOCK
命令以讀鎖鎖定所有資料庫中的所有表。檢視章節 。如果你有一個可以及時建立檔案快照的檔案,例如 Veritas,這將是得到備份的非常方便方式。
注意:LOCK TABLES
不是事務安全的,在嘗試鎖定一個表之前,將自動地提交所有的活動事務。
6.7.3 SET TRANSACTION
句法
SET [GLOBAL | SESSION] TRANSACTION ISOLATION LEVEL { READ UNCOMMITTED | READ COMMITTED | REPEATABLE READ | SERIALIZABLE }
設定全域性的、整個會話或下一個事務的事務隔離級。
預設行為是設定下一個(未啟動的)事務的隔離級。如果你使用 GLOBAL
關鍵詞,語句為所有在那個點上建立的新連線設定預設的全域性事務隔離級。為了這樣做,你需要有 SUPER
許可權。使用 SESSION
關鍵詞為當前連線所有將來執行的事務設定預設的事務隔離級。
你可以使用 --transaction-isolation=...
為 mysqld
設定預設的全域性隔離級。檢視章節 。
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/10748419/viewspace-998562/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- MySQL事務與鎖MySql
- mysql之鎖與事務MySql
- 【MySQL 5.7參考手冊】8.14.2 General Thread StatesMySqlthread
- DOJO API 中文參考手冊API
- MySQL入門--事務與鎖MySql
- mysql鎖與事務總結MySql
- MySQL(一):MySQL資料庫事務與鎖MySql資料庫
- MySQL8-中文參考-三-MySql
- MySQL8-中文參考-三十二-MySql
- MySQL 事務和鎖MySql
- MySQL事務和鎖MySql
- 譯-MYSQL5.7參考手冊--數值型別概述MySql型別
- mysql事務處理與鎖機制MySql
- Mysql鎖與事務隔離級別MySql
- 譯-MYSQL5.7參考手冊--11.1.1數值型別概述MySql型別
- MySQL – 事務的啟動 / 設定 / 鎖 / 解鎖——入門MySql
- MySQL 筆記 - 事務&鎖MySql筆記
- 譯-MYSQL5.7參考手冊--11.1.2日期與時間型別概述MySql型別
- mysql 事務處理及表鎖定深入簡析MySql
- 深入理解Mysql——鎖、事務與併發控制MySql
- Mysql事務隔離級別與鎖機制MySql
- 深入理解 MySQL—鎖、事務與併發控制MySql
- JavaScript物件參考手冊JavaScript物件
- 降級MySQL(參考MySQL官方文件)MySql
- mysql 事務,鎖,隔離機制MySql
- 重新學習MySQL資料庫6:淺談MySQL的中事務與鎖MySql資料庫
- MySQL事務與併發MySql
- mysql許可權參考MySql
- docker 安裝 MySQL (參考)DockerMySql
- 詳解Mysql事務隔離級別與鎖機制MySql
- MySQL 核心三劍客 —— 索引、鎖、事務MySql索引
- mysql事務隔離級別和鎖MySql
- MySQL資料庫6:Go與MySQL事務MySql資料庫Go
- git參考手冊--文字說明+git速查命令表(圖片)Git
- 設定mysql 事務鎖超時時間 innodb_lock_wait_timeoutMySqlAI
- Python sys模組參考手冊Python
- Python os模組參考手冊Python
- 20200116 - HTML 和 CSS 參考手冊HTMLCSS
- PHP-imap 使用參考手冊PHP