7 MySQL 事務與鎖定命令

2021-06-04 01:26:48 字數 4379 閱讀 3007

預設的,mysql 執行在autocommit模式。這就意味著,當你執行完乙個更新時,mysql 將立刻將更新儲存到磁碟上。

如果你使用事務安全表 (例如innodbbdb),通過下面的命令,你可以設定 mysql 為非autocommit模式:

set autocommit=0
在此之後,你必須使用commit來儲存你的更改到磁碟上,或者使用rollback,如果你希望忽略從你的事務開始所做的更改。

如果你希望為一系列語句從autocommit模式轉換,你可以使用start transactionbeginbegin work語句:

start transaction;

select @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 transactionset autocommit=0,你應該使用 mysql 二進位制日誌做備份以代替老的更新日誌。事務處理被以乙個大塊形式儲存在二進位制日誌中,在commit上面,為了保護回滾的事務,而不是被儲存的。檢視章節 4.9.4 二進位制日誌。 如果您使用起動事務處理或集autocommit=0 ,您應該使用mysql 二進位制日誌為備份代替更舊的更新日誌。 事務處理儲存在二進位制登入一大塊,做,保證, 滾的事務處理不儲存。 參見部分4 。9.4 二進位制日誌。

下列命令自動的結束乙個事務 (就好像你在執行這個命令之前,做了乙個commit):

命令命令命令

alter tablebegincreate index

drop databasedrop tablerename table

truncate

你可以使用set transaction isolation level ...改變事務的隔離級。檢視章節 7.3set transaction句法。

lock tables tbl_name [as alias] 

[, tbl_name [as alias] ...]

...unlock tables

lock tables為當前執行緒鎖定表。unlock tables釋放當前執行緒擁有的所有鎖定。當執行緒發出另乙個lock tables,或當與伺服器的連線被關閉時,被當前執行緒鎖定的所有表將被自動地解鎖。

為了在 mysql 4.0.2 使用lock tables,你必須擁有乙個全域性的lock tables許可權和乙個在相關表上的select許可權。在 mysql 3.23 中,你對該錶需要有selectinsertdeleteupdate許可權。

使用lock tables的主要原因是,仿效事務處理或在更新表時得到更快的速度。此後會有更詳細的描述。

如果乙個執行緒在乙個表上得到乙個read鎖,該執行緒 (和所有其它執行緒) 只能從表中讀取。如果乙個執行緒在乙個表上得到乙個write鎖,那麼只有擁有這個鎖的執行緒可以從表中讀取和寫表。其它的執行緒被阻塞。

read localread之間的不同就在於,當鎖被載入時,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安全地殺死乙個正在表鎖定的執行緒。檢視章節 4.5.5kill句法。

注意,你不應該鎖定你正在對其使用insert delayed的表。這是因為,在這種情況下,insert是通過單獨的執行緒完成的。

通常,你不需要鎖定任何表,因為所有單update語句都是原子的;其它的執行緒無法干擾當前執行的 sql 語句。當你無論如何希望鎖定表時,這裡有一些情況:

通過使用遞增更新 (update customer set value=value+new_value) 或last_insert_id()函式,你可以在很多情況下避免使用lock tables

你也可以使用使用者級鎖定函式get_lock()release_lock()解決一些情況,這些鎖被儲存在伺服器上的乙個雜湊表中,並以pthread_mutex_lock()pthread_mutex_unlock()實現以獲得高速度。檢視章節 3.2 輔助功能函式。

檢視章節 5.3.1 mysql 如何鎖定表,以獲取關於鎖定方案的更多資訊。

注意:lock tables不是事務安全的,在嘗試鎖定乙個表之前,將自動地提交所有的活動事務。

set [global | session] transaction isolation level

設定全域性的、整個會話或下乙個事務的事務隔離級。

你可以使用--transaction-isolation=...mysqld設定預設的全域性隔離級。檢視章節 4.1.1mysqld命令列選項。

(t113)

7 MYSQL 實戰命令

登入資料庫 mysql uroot p12345678 查詢所有的資料庫 show databases 切換到指定的資料庫 user 資料庫名稱 查詢所有使用者 select from mysql.user 查詢資料庫中所有表名 select table name from information ...

事務與鎖定 提交事務

drop table emp if exists?create table emp empid number 5 empname varchar2 100 empage number 5 declare v empname varchar 50 chenzw begin delete from em...

7 MySQL結果資料處理與函式

複習 查詢 select 列名 from 表 去重 distinct 排序 order by 列1 列2 排序方法 asc desc.限定返回行數 limit n limit n,m 過濾 where 操作符 and or in not between and is null is not null...