1.概念:给单独的一行记录加锁,主要应用于innodb表存储引擎mysql
2.特色:在innodb存储引擎中应用比较多,支持事务、开销大、加锁慢;会出现死锁;锁的粒度小,并发状况下,产生锁等待的几率比较低,因此支持的并发数比较高。sql
1.概念:事务是一系列操做组成的工做单元,该工做单元内的操做是不可分割的,也就是说要么所有都执行,要么所有不执行。数据库
2.特性:ACIDbash
1.问题session
注:不可重复读的重点是修改,一样的条件,你读取过的数据,再次读取出来发现值不同。并发
幻读的重点在于新增或者删除,一样的条件,第 1 次和第 2 次读出来的记录数不同。spa
2.解决方案--数据库隔离机制code
解决了丢失更新,可是会出现脏读、不可重复读、幻读。cdn
解决了丢失更新和脏读,可是会出现不可重复读和幻读。blog
解决了丢失更新、脏读和不可重复读,可是会出现幻读。
解决了全部的问题。
注:乐观所能够解决幻读。
查看mysql事务隔离级别:show variables like 'tx_iso%';
前提:set autocommit=0; // 设置自动提交事务为手动提交
/* 行锁案例*/
create table lock_two(
id int,
col int
)engine=innodb;
insert into lock_two(id,col) values (1,1);
insert into lock_two(id,col) values (2,2);
insert into lock_two(id,col) values (3,3);
复制代码
1.在session1中执行update : update lock_two set col=11 where id=1;
(1)分别在session1和session2中查询lock_two,看id为1的记录的col是否修改了。
发现session1 的记录修改了,session2中的记录没有被修改。
(2)在session1中执行commite后,而后再在session2中查询:
发现session2中的表数据改变了。
2.在session1中执行update:update lock_two set col=11 where id=1,不执行commit;
在session2中执行uodate :update lock_two set col=11 where id=1,不执行commit;
发现session2中的update发生阻塞,而且超过一段时间报错。
3.在session1中执行update:update lock_two set col=22 where id = 2; 不执行commit
在session2中执行另外一条update:update lock_two set col=33 where id = 3;
4.在lock_two中建立索引,
create index idx_id on lock_two(id);
create index idx_col on lock_two(col);
复制代码
而后重复第3步,
发现session2能够更新,不会产生阻塞。由于用上了索引,至关于行锁。
结论:若是没有用上索引,行锁变成表锁
begin;
select * from lock_two where id=2 for update;
复制代码
1.定义
在范围查找的状况下, innodb会给范围条件中的数据加上锁,不管数据是不是否真实存在。
2.例子
在session1中update:update lock_two set col=666 where id>2 and id<8;
1) 在session2中执行insert:insert into lock_two values(9,99);
插入执行成功!
2) 在session2中执行insert:insert into lock_two values(7,77);
插入阻塞,一段时间后报错!
执行select:select * from lock_two where id=4;
查询成功!
建议:在innodb中,由于有间隙锁的存在,最好在where中少使用这种范围查找。
show status like 'innodb_row_lock%';
说明: