表結構以下:php
delimiter $$mysql
CREATE TABLE `wrox_shop_order` (
`o_id` int(11) NOT NULL AUTO_INCREMENT,
`order_date` datetime DEFAULT NULL,
`order_status` varchar(45) DEFAULT 'CREATED',
`customer_id` int(11) DEFAULT NULL,
PRIMARY KEY (`o_id`),
KEY `orderDate` (`order_date`) //這裏最開始不加,後面添上的
) ENGINE=InnoDB AUTO_INCREMENT=164 DEFAULT CHARSET=utf8$$sql
這樣一個數據表:數據庫
開啓兩個mysql客戶端:工具
由於工做須要 我在mysql workbench裏面用了一個 存儲過程,相對簡單的一個: delimiter $$
/××
××param1 表示輸入的值,param2,param3 是輸出變量:後面使用
××select @m1 as a,@m2 as b; 能夠獲得輸出的值
××/ CREATE PROCEDURE last_delete_info (IN param1 datetime,OUT param2 INT,OUT param3 varchar(45)) BEGIN select o_id,order_status into param2,param3 from wrox_shop_order where order_date=param1 limit 1 for update; #delete from wrox_shop_order where o_id=param2; //這一行後面用@DELETE來表示 END $$ delimiter ;
首先在workBench裏執行:測試
操做一:spa
set autocommit=0;
call last_delete_info('2013-04-01 19:49:58',@m1,@m2); select @m1 as a,@m2 as b;
結果:
此時 o_id 爲3的行是否被鎖住了呢?打開mysql 命令行到相應數據庫中執行:命令行
操做二:code
delete from wrox_shop_order where o_id=3;blog
結果刪除不了數據,說明該行數據被加了鎖,那麼刪除其餘數據呢?
delete from wrox_shop_order where o_id=4 or o_id=5;
結果仍是刪除不了數據,
從這裏咱們驗證了不少人都驗證的問題,若是innodb 沒有在加索引的行上加鎖,那麼會使用表鎖
接下來若是有注意最開始的建立語句有這麼一個:KEY `orderDate` (`order_date`) //這裏最開始不加,後面添上的
那麼如今去個order_date加個索引:
一個小提示:如今autocomint=0;直接改的話是改不了的。須要commint 後才能夠加索引;而後執行:
ALTER TABLE `test`.`wrox_shop_order` ADD INDEX `order_date` (`order_date` ASC) ;
而後從新執行上面兩個mysql客戶端工具的操做,執行到第二步的時候命令行仍是沒法刪除,可是若是刪除其餘數據倒是能夠的
說明INNODB在加了索引的的行上加鎖是加的行級鎖,並且是對索引加的鎖
今天又作了一些測試,再次總結一下:
好比:
delimiter $$ CREATE TABLE `akulubala` ( `id` int(11) NOT NULL AUTO_INCREMENT, `artist` varchar(100) NOT NULL, `title` varchar(100) NOT NULL, `index_column` tinyint, PRIMARY KEY (`id`), KEY `index_c` (`index_column`) ) ENGINE=InnoDB AUTO_INCREMENT=7 DEFAULT CHARSET=utf8$$
執行:
set autocommit=0;
SELECT * FROM akulubala.akulubala where index_column=9 for update;
另一個進程執行:
由以上三點能夠得出鎖是對索引的鎖,即對索引加鎖,使用被加鎖的索引時都會等待,而且對由索引查出的行加鎖,若是更新數據沒有用到任何索引,就會全表加鎖..
另外:事務和鎖是兩回事,事務有四個隔離級別,不一樣的隔離級別有不一樣的鎖定機制:INNODB 默認是可重複讀