表结构以下: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 默认是可重复读