MySQL性能优化(九)-- 锁机制之行锁

栏目: 数据库 · 发布时间: 4年前

内容简介:1.概念:给单独的一行记录加锁,主要应用于innodb表存储引擎2.特点:在innodb存储引擎中应用比较多,支持事务、开销大、加锁慢;会出现死锁;锁的粒度小,并发情况下,产生锁等待的概率比较低,所以支持的并发数比较高。1.概念:事务是一系列操作组成的工作单元,该工作单元内的操作是不可分割的,也就是说要么全部都执行,要么全部不执行。

1.概念:给单独的一行记录加锁,主要应用于innodb表存储引擎

2.特点:在innodb存储引擎中应用比较多,支持事务、开销大、加锁慢;会出现死锁;锁的粒度小,并发情况下,产生锁等待的概率比较低,所以支持的并发数比较高。

二、数据库事务

1.概念:事务是一系列操作组成的工作单元,该工作单元内的操作是不可分割的,也就是说要么全部都执行,要么全部不执行。

2.特性:ACID

  • 原子性:事务是最小的工作单元,不可分割,要么都做,要么都不做
  • 一致性:事务执行前和执行后的数据要保证正确性,数据完整性没有被破坏。
  • 隔离性:在并发事务执行的时候,一个事务对其他事务不会产生影响。
  • 持久性:一个事务一旦提交,它对数据库中的数据的改变就应该是永久性的

三、多个事务并发执行 问题及解决方案

1.问题

  • 丢失更新:在没有事务隔离的情况下,两个事务同时更新一条数据,后一个事务 会 覆盖前面事务的更新,导致前面的事务丢失更新。
  • 脏读:事务A先更新数据,但是没有提交,事务B读到了事务A没有提交的数据。
  • 不可重复读:事务A中,先读到一条数据,事务A还没有结束,此时,事务B对该条数据进行了修改操作,事务A又读到了这条数据,事务A两次读到的数据不同。
  • 幻读:事务A先读到一批数据,假设读到10条,事务B插入了一条数据,此时,事务A又读这一批数据,发现多了一条,好像幻觉一样。

注:不可重复读的重点是修改,同样的条件,你读取过的数据,再次读取出来发现值不一样。

幻读的重点在于新增或者删除,同样的条件,第 1 次和第 2 次读出来的记录数不一样。

2.解决方案--数据库隔离机制

  1. 未提交读(read uncommitted):这是数据库最低的隔离级别,允许一个事务读另一个事务未提交的数据。

解决了丢失更新,但是会出现脏读、不可重复读、幻读。

  1. 提交读(read committed):一个事务更新的数据 在提交之后 才可以被另一个事务读取,即一个事务不可以读取到另一个事务未提交的数据。

解决了丢失更新和脏读,但是会出现不可重复读和幻读。

  1. 可重复读(repeatale read):这是数据库默认的事务隔离级别,保证一个事务在相同条件下前后两次读取的数据是一致的。

解决了丢失更新、脏读和不可重复读,但是会出现幻读。

  1. 序列化(serializable):这是数据库最高的隔离级别。事务串行执行,不会交叉执行。

解决了所有的问题。

注:乐观所可以解决幻读。

四、行锁的特性

查看 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是否修改了。

MySQL性能优化(九)-- 锁机制之行锁

发现session1 的记录修改了,session2中的记录没有被修改。

(2)在session1中执行commite后,然后再在session2中查询:

MySQL性能优化(九)-- 锁机制之行锁

发现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;

MySQL性能优化(九)-- 锁机制之行锁

发现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;

MySQL性能优化(九)-- 锁机制之行锁

此时,session2中的update发生阻塞,在没发生错误的情况下,session1执行commit,session2中的update会马上执行。

4.在lock_two中创建索引,

create index idx_id on lock_two(id);
create index idx_col on lock_two(col);
复制代码

然后重复第3步,

MySQL性能优化(九)-- 锁机制之行锁

发现session2可以更新,不会产生阻塞。因为用上了索引,相当于行锁。

结论:如果没有用上索引,行锁变成表锁

五、手动锁一行记录格式

begin;

select * from lock_two where id=2 for update;
复制代码
  1. 在session1中执行上面语句,在ssesion2中可以查看,但是不可以修改 sesion1中的for update 的记录。
  2. 当session1中执行commit后,seesion2中的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中少使用这种范围查找。

欢迎关注我的公众号,第一时间接收最新文章~ 搜索公众号:

或者 扫描下方二维码:


以上所述就是小编给大家介绍的《MySQL性能优化(九)-- 锁机制之行锁》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

Machine Learning

Machine Learning

Kevin Murphy / The MIT Press / 2012-9-18 / USD 90.00

Today's Web-enabled deluge of electronic data calls for automated methods of data analysis. Machine learning provides these, developing methods that can automatically detect patterns in data and then ......一起来看看 《Machine Learning》 这本书的介绍吧!

CSS 压缩/解压工具
CSS 压缩/解压工具

在线压缩/解压 CSS 代码

URL 编码/解码
URL 编码/解码

URL 编码/解码

MD5 加密
MD5 加密

MD5 加密工具