參考:http://www.cnblogs.com/bigfish--/archive/2012/02/18/2356886.htmlhtml
因爲InnoDB預設是Row-Level Lock,因此只有「明確」的指定主鍵,MySQL纔會執行Row lock (只鎖住被選取的資料例) ,不然MySQL將會執行Table Lock (將整個資料表單給鎖住)。
舉個例子:
假設有個表單products ,裏面有id跟name二個欄位,id是主鍵。
例1: (明確指定主鍵,而且有此筆資料,row lock)
SELECT * FROM products WHERE id='3' FOR UPDATE;
例2: (明確指定主鍵,若查無此筆資料,無lock)
SELECT * FROM products WHERE id='-1' FOR UPDATE;
例2: (無主鍵,table lock)
SELECT * FROM products WHERE name='Mouse' FOR UPDATE;
例3: (主鍵不明確,table lock)
SELECT * FROM products WHERE id<>'3' FOR UPDATE;
例4: (主鍵不明確,table lock)
SELECT * FROM products WHERE id LIKE '3' FOR UPDATE;
注1: FOR UPDATE僅適用於InnoDB,且必須在交易區塊(BEGIN/COMMIT)中才能生效。
注2: 要測試鎖定的情況,能夠利用MySQL的Command Mode ,開二個視窗來作測試。mysql
由上面的InnoDB 已經交易區塊引出兩個問題。sql
1. what is InnoDB?數據庫
MySQL是咱們比較經常使用的一種數據庫軟件。它有着諸多的優勢,如開源的,免費的等等。其實它還有一個很好的特色,那就是有多種引擎能夠供你選擇。若是賽車手能根據不一樣的路況,地形隨手更換與之最適宜的引擎,那麼他們將創造奇蹟。然而目前他們還作不到那樣便捷的更換引擎,可是咱們卻能夠!
所謂知己知彼方可百戰不殆,要想將它們發揮到極致,首先咱們應該來認識一下MySQL提供給咱們的這幾種引擎。
通常來講,MySQL有如下幾種引擎:ISAM、MyISAM、HEAP、InnoDB和Berkley(BDB)。注意:不一樣的版本支持的引擎是有差別的。併發
進一步:測試
如何查看MySQL的當前存儲引擎?ui
通常狀況下,mysql會默認提供多種存儲引擎,你能夠經過下面的查看:htm
看你的mysql如今已提供什麼存儲引擎:
mysql> show engines;blog
以上說明個人mysql默認使用的InnoDB引擎,而且支持MyISAM,memory,archive,Mrg_myisam。事務
後面還跟着解釋, InnoDB 的解釋是:支持事務,行級別鎖定,外鍵。
看你的mysql當前默認的存儲引擎:
mysql> show variables like '%storage_engine%';
你要看某個表用了什麼引擎(在顯示結果裏參數engine後面的就表示該表當前用的存儲引擎):
mysql> show create table 表名;
其實這是必定的,由於個人mysql引擎就是InnoDB,默認狀況下建立的表當前也是以InnoDB爲引擎的嘍
2. what is 交易區塊?
參考:http://hi.baidu.com/cuihu0706/blog/item/1dd6ccb1621c355709230278.html
事務處理在各類管理系統中都有着普遍的應用,好比人員管理系統,不少同步數據庫操做大都須要用到事務處理。好比說,在人員管理系統中,你刪除一我的員,你即須要刪除人員的基本資料,也要刪除和該人員相關的信息,如信箱,文章等等,這樣,這些數據庫操做語句就構成一個事務!
刪除的SQL語句
delete from userinfo where ~~~
delete from mail where ~~
delete from article where~~
~~
若是沒有事務處理,在你刪除的過程當中,假設出錯了,只執行了第一句,那麼其後果是不可思議的!
但用事務處理。若是刪除出錯,你只要rollback就能夠取消刪除操做(實際上是隻要你沒有commit你就沒有確實的執行該刪除操做) 通常來講,在商務級的應用中,都必須考慮事務處理的!
MYSQL數據庫從4.1就開始支持事務功能,聽說5.0將引入存儲過程^_^
先簡單介紹一下事務吧!事務是DBMS得執行單位。它由有限得數據庫操做序列組成得。但不是任意得數據庫操做序列都能成爲事務。通常來講,事務是必須知足4個條件(ACID)
原子性(Autmic):事務在執行性,要作到「要麼不作,要麼全作!」,就是說不容許事務部分得執行。即便由於故障而使事務不能完成,在rollback時也要消除對數據庫得影響!
一致性(Consistency):事務得操做應該使使數據庫從一個一致狀態轉變倒另外一個一致得狀態!就拿網上購物來講吧,你只有即讓商品出庫,又讓商品進入顧客得購物籃才能構成事務!
隔離性(Isolation):若是多個事務併發執行,應象各個事務獨立執行同樣!
持久性(Durability):一個成功執行得事務對數據庫得做用是持久得,即便數據庫應故障出錯,也應該可以恢復!
MYSQL的事務處理主要有兩種方法。
一、用begin,rollback,commit來實現
begin 開始一個事務
rollback 事務回滾
commit 事務確認
二、直接用set來改變mysql的自動提交模式
MYSQL默認是自動提交的,也就是你提交一個QUERY,它就直接執行!咱們能夠經過
set autocommit=0 禁止自動提交
set autocommit=1 開啓自動提交
但注意當你用 set autocommit=0 的時候,你之後全部的SQL都將作爲事務處理,直到你用commit確認或rollback結束,注意當你結束這個事務的同時也開啓了個新的事務!按第一種方法只將當前的做爲一個事務!我的推薦使用第一種方法!
MYSQL中只有INNODB和BDB類型的數據表才能支持事務處理!其餘的類型是不支持的!(切記!)
MYSQL5.0 WINXP下測試經過~ ^_^
mysql> use test;
Database changed
mysql> CREATE TABLE `dbtest`(
-> id int(4)
-> ) TYPE=INNODB;
Query OK, 0 rows affected, 1 warning (0.05 sec)
mysql> select * from dbtest
-> ;
Empty set (0.01 sec)
mysql> begin;
Query OK, 0 rows affected (0.00 sec)
mysql> insert into dbtest value(5);
Query OK, 1 row affected (0.00 sec)
mysql> insert into dbtest value(6);
Query OK, 1 row affected (0.00 sec)
mysql> commit;
Query OK, 0 rows affected (0.00 sec)
mysql> select * from dbtest;
+------+
| id |
+------+
| 5 |
| 6 |
+------+
2 rows in set (0.00 sec)
mysql> begin;
Query OK, 0 rows affected (0.00 sec)
mysql> insert into dbtest values(7);
Query OK, 1 row affected (0.00 sec)
mysql> rollback; //這裏回滾了
Query OK, 0 rows affected (0.00 sec)
mysql> select * from dbtest;
+------+
| id |
+------+
| 5 |
| 6 |
+------+
2 rows in set (0.00 sec)
mysql>
既然已經知道了相關的知識,那麼下面就用for update來鎖定行,進行試驗
以上例中student表爲例,
1. 使用begin開始一個事務
2. 利用select * for update 鎖定行,
3. 在新窗口中驗證非選中行是否被鎖定 ----未被鎖定
4. 在新窗口中驗證選中行是否被鎖定 -----鎖定,update語句在等待了一段時間後失敗。