mysql第二天 锁

如果没有锁,那么并发性会更强,但是数据安全性会有问题。因此数据库会给数据加锁。

共享锁与排他锁

也就是读写锁,共享锁可以叠加共享锁但是不能加排他锁, 排他锁则不能叠加。
根据隔离级别等等,mysql会隐式的给数据自动加锁
此外还可以使用share in model, for update 等语句显示的加锁

粒度锁

粒度越细,维护锁的开销越大,并发性越高,数据越不安全。 通常有如下两种

- 行锁

只给一行数据加锁

- 表锁

给整张表加锁, 一般Alter table会使用表锁

意向锁

mysql为了提高冲突监测性能而存在的一种锁。是给其上一级所加的锁,所以在mysql中通常为表锁。

比如一个事务,给两行加了排他锁,又有一个事务想要给整个表加共享锁,这个时候就要去查看所有的表的行是否有锁策略不能加共享锁。 如果有了意向锁,那么事务1就能再给两行加排他锁的同时,给整个表加IX, 这样事务2不用遍历就能知道不可以加S锁了。

悲观锁与乐观锁

A,B两个人同时在系统上进行操作,比如要修改一份订单。 当A正在修改准备提交前向上厕所,这儿时候B修改完订单并且提交了。 这个时候A回来了再提交就会出现问题,B的修改被覆盖了。

- 悲观锁

for update, share in model语句

使用悲观锁,则会在操作期间全程对数据进行加锁,其他人不能再次修改。这样会造成比较长时间的阻塞。

适用于短事务,写量比较大的情况。

- 乐观锁

乐观锁通过在数据库中新增一个version字段,操作后给version + 1. 提交时比较,如果比数据库中的大,则提交。大概的代码是:

    if(connection.update("update set name=‘123‘ where id=1 and version < #current_version#") > 0){
        // 表示更新成功了
    }
这种适用于读多,写少,并且写有可能会用很长时间的情况。

死锁

比如有两个事物:

事物1

update table1 set name=‘1‘ where id=1;
// sleep 1
update table1 set name=‘2‘ where id=2;
commit;

事物2

update table1 set name=‘2‘ where id=2;
// sleep 2
update table1 set name=‘1‘ where id=1;
commit;

上面的语句如果恰巧一起执行到sleep1 和sleep2,那么就会造成死锁。 一般有三种做法解决:

  • 一次锁所有数据
  • 保持锁的顺序
  • 允许死锁,然后kill掉代价最小的事务。回滚之

间隙锁

执行select .. from where id between这样的语句的时候锁定这一区间,不能插入或者删除数据,以防止幻读。

MVCC 多版本并发控制

mysql维护一个系统版本号,每次有新的事物开始的时候递增。

每行后面保存两个隐藏列。 一个创建时版本号C,一个删除时版本号D

  • INSERT 新增的行往C里写入当前系统版本号。 这样新事物可以通过这个版本号保证不查到他
  • DELETE 为删除的行写D字段为当前系统版本号。
  • UPDATE 插入一行新数据写C为当前系统版本号,老数据写D为当前系统版本号。
  • SELECT 的时候只查 C<=当前版本 && (D > 当前版本 || D is not defined) 这样主要是为了在不加锁的情况下,一个事务能够读取到事务开始前已经存在且未被删除,且没有经过修改的数据。 也就是解决脏读的问题。即该事物开始之后的其他事务的各种修改事务提交都不会对当前事务的读取产生影响。同时也解决了幻读的问题

语句与锁

  • InnoDB 的行锁是基于索引的,如果没有索引,或者不能使用索引则是表锁
  • select … from 一致性非阻塞读,不上锁。
  • select … from where lock in share mode 共享锁
  • select … from where … for update 排他锁
  • update .. where 排他锁
  • delete … from 排他锁

    下面的例子来看锁的排他性

    事务1

 set autocommit=0;
 begin;
 SELECT * FROM biz_pay_task where id = 1 FOR UPDATE;
 // wait
 commit;

事务2

 set autocommit=0;
 begin;
 SELECT * FROM biz_pay_task where id = 1 LOCK IN SHARE MODE;
 commit;

事务2在执行SELECT LOCK IN SHARE MODE的时候会阻塞,知道事务1commit之后才会完成。

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-10-06 10:57:32

mysql第二天 锁的相关文章

【MySQL】乐观锁和悲观锁

最近学习了一下数据库的悲观锁和乐观锁,根据自己的理解和网上参考资料总结如下: 悲观锁介绍(百科): 悲观锁,正如其名,它指的是对数据被外界(包括本系统当前的其他事务,以及来自外部系统的事务处理)修改持保守态度,因此,在整个数据处理过程中, 将数据处于锁定状态.悲观锁的实现,往往依靠数据库提供的锁机制(也只有数据库层提供的锁机制才能真正保证数据访问的排他性,否则,即使在本系统中实现了 加锁机制,也无法保证外部系统不会修改数据). 使用场景举例:以MySQL InnoDB为例 商品goods表中有一

巧用MySQL InnoDB引擎锁机制解决死锁问题(转)

该文会通过一个实际例子中的死锁问题的解决过程,进一步解释innodb的行锁机制 最近,在项目开发过程中,碰到了数据库死锁问题,在解决问题的过程中,笔者对MySQL InnoDB引擎锁机制的理解逐步加深. 案例如下: 在使用Show innodb status检查引擎状态时,发现了死锁问题: *** (1) TRANSACTION: TRANSACTION 0 677833455, ACTIVE 0 sec, process no 11393, OS thread id 278546 starti

mysql事务和锁InnoDB(转)

背景 MySQL/InnoDB的加锁分析,一直是一个比较困难的话题.我在工作过程中,经常会有同事咨询这方面的问题.同时,微博上也经常会收到MySQL锁相关的私信,让我帮助解决一些死锁的问题.本文,准备就MySQL/InnoDB的加锁问题,展开较为深入的分析与讨论,主要是介绍一种思路,运用此思路,拿到任何一条SQL语句,都能完整的分析出这条语句会加什么锁?会有什么样的使用风险?甚至是分析线上的一个死锁场景,了解死锁产生的原因. 注:MySQL是一个支持插件式存储引擎的数据库系统.本文下面的所有介绍

MYSQL 解锁与锁表

解锁 第一种 show processlist; 找到锁进程,kill id ; 第二种 mysql>UNLOCK TABLES; 锁表 锁定数据表,避免在备份过程中,表被更新 mysql>LOCK TABLES tbl_name READ; 为表增加一个写锁定: mysql>LOCK TABLES tbl_name WRITE;

MySQL中的锁(表锁、行锁)

锁是计算机协调多个进程或纯线程并发访问某一资源的机制.在数据库中,除传统的计算资源(CPU.RAM.I/O)的争用以外,数据也是一种供许多用户共享的资源.如何保证数据并发访问的一致性.有效性是所在有数据库必须解决的一个问题,锁冲突也是影响数据库并发访问性能的一个重要因素.从这个角度来说,锁对数据库而言显得尤其重要,也更加复杂. 概述 相对其他数据库而言,MySQL的锁机制比较简单,其最显著的特点是不同的存储引擎支持不同的锁机制. MySQL大致可归纳为以下3种锁: 表级锁:开销小,加锁快:不会出

MySQL- InnoDB锁机制

InnoDB与MyISAM的最大不同有两点:一是支持事务(TRANSACTION):二是采用了行级锁.行级锁与表级锁本来就有许多不同之处,另外,事务的引入也带来了一些新问题.下面我们先介绍一点背景知识,然后详细讨论InnoDB的锁问题. 背景知识 事务(Transaction)及其ACID属性 事务是由一组SQL语句组成的逻辑处理单元,事务具有以下4个属性,通常简称为事务的ACID属性. 原子性(Atomicity):事务是一个原子操作单元,其对数据的修改,要么全都执行,要么全都不执行. 一致性

Mysql中那些锁机制之MyISAM

说到锁机制之前,先来看看Mysql的存储引擎,毕竟不同的引擎的锁机制也随着不同. 三类常见引擎: MyIsam :不支持事务,不支持外键,所以访问速度快.锁机制是表锁,支持全文索引 InnoDB :支持事务.支持外键,所以对比MyISAM,InnoDB的处理效率差一些,并要占更多的磁盘空间保留数据和索引.锁机制是行锁,不支持全文索引 Memory:数据是存放在内存中的,默认哈希索引,非常适合存储临时数据,服务器关闭后,数据会丢失掉. 如何选择存储引擎: MyISAM:应用是以读操作和插入操作为主

mysql事务和锁InnoDB

背景 MySQL/InnoDB的加锁分析,一直是一个比较困难的话题.我在工作过程中,经常会有同事咨询这方面的问题.同时,微博上也经常会收到MySQL锁相关的私信,让我帮助解决一些死锁的问题.本文,准备就MySQL/InnoDB的加锁问题,展开较为深入的分析与讨论,主要是介绍一种思路,运用此思路,拿到任何一条SQL语句,都能完整的分析出这条语句会加什么锁?会有什么样的使用风险?甚至是分析线上的一个死锁场景,了解死锁产生的原因. 注:MySQL是一个支持插件式存储引擎的数据库系统.本文下面的所有介绍

转载 深入浅出mysql事务处理和锁机制

1. 事务处理和并发性 1.1. 基础知识和相关概念 1 )全部的表类型都可以使用锁,但是只有 InnoDB 和 BDB 才有内置的事务功能. 2 )使用 begin 开始事务,使用 commit 结束事务,中间可以使用 rollback 回滚事务. 3 )在默认情况下, InnoDB 表支持一致读. SQL 标准中定义了 4 个隔离级别: read uncommited , read commited , repeatable read , serializable . read uncomm