Innodb中的锁机制

使用数据库的目的在于数据共享,需要考虑数据并发访问问题。解决方案就是锁机制
锁主要包括全局锁、表锁、行锁、乐观锁和悲观锁,需要解决的问题是死锁
存储引擎
存储引擎定义 MySQL 中的数据、索引以及其它的数据库对象如何存储,是一套文件系统的实现
查看所有的存储引擎 show engines ;
Innodb中的锁机制_第1张图片

 常见的存储引擎:MyISAMInnodbmemory    

MyISAM 采用的是全表锁,具有较高的查询执行速度,不支持事务和外键,并发性能差,但是占用
空间相对较小,对于事务没有要求,一般主要以 select insert 为主的应用可以使用这个引擎
Innodb 采用的是行级锁,可以提供具有提交、回滚和恢复能力的事务安全,支持自增长类,支持
外键约束,并发性能强,一般所需要占用的空间是 MyISAM 2.5 倍以上,处理效率相对差一些
Memory 采用的是全表锁,存储数据在内存中,速度快,但是占用和数据量成正比的内存空间,而
且数据在 MySQL 重启时丢失,默认使用 hash 索引,检索效率高,但是不适合范围查找,主要用于
缓存内容变化不频繁的表
archive 这种类型的表只支持 insert select ,不支持 delete update replace ,不使用索引
csv 这些表保存在服务器的单个文件中,它包含了用逗号间隔的数据。
Innodb MyISAM 的区别
        Innodb支持事务, MyISAM 不支持, Innodb 针对每条 SQL 语句都默认封装为事务,自动提交,这样会影响执行速度
        Innodb支持外键约束, MyISAM 不支持。所以对于一个包含外键的 innodb 表转换为 MyISAM 会失败
        Innodb采用的时聚集索引,数据文件和索引绑定,必须有主键,通过主键查询效率很高;但是辅 助索引需要两次查询,因此在Innodb中主键不应该过大; MyISAM 采用的是非聚集索引,所以数据 文件分离
        innodb不保存数据的总行数,执行 select count(*) 需要全表扫描;而 MyISAM 使用一个变量保
存了表的总行数,所以执行 count(*) 查询时速度很快
        Innodb5.5-不支持全文索引, MyISAM 支持全文索引,查询效率上 MyISAM
选择依据:
如果没有特殊要求,使用默认的 innodb 即可
        MyISAM:以读取和插入为主的应用,比如博客系统、新闻网站等。搜索引擎采用 NoSQL 类型的数据库ES 提供
        Innodb:更新删除操作效率要求较高或者要求保证数据的完整性,同时考虑并发量要求高的场景下使用,例如OA 之类的管理系统。因为支持事务和外键所以能够很好的保证数据完整性
Innodb中的锁机制_第2张图片 
Innodb 存储引擎即支持行级锁,也支持表级锁,默认情况下使用行级锁。锁类型包括共享 S 锁、排他 X锁、意向共享IS 锁和意向 IX 排他锁。
意向锁就是为了让表锁可以快速感知是否有行级锁的存在,以防止表锁干扰行锁的执行
Innodb中的锁机制_第3张图片

 

表级锁
锁的颗粒度为整个表
lock tables 表名称 read/write ,其中 read 是共享锁,一旦锁定则共享读取数据, write 是排他锁,
只有加锁的客户端可以读写,其它客户端不可读也不可写
解锁 unlock tables
行级锁
锁的颗粒度为表中的特定的一行或者多行
共享锁 select * from 表名称 where 条件 lock in share mode ;
排他锁 select * from 表名称 where 条件 for update ;
注意:所谓的行锁并不是直接锁定特定行的数据,实际上是锁定一个子范围,所以也称为间隙锁。例如
select * from tb_student where id<20 lock in share mode 实际上并不是锁定 id<20 的现有数
据,而是锁定 id<20 的范围,例如插入 id 18 的新记录失败
死锁问题
        死锁是指两个或多个事务在同一资源上相互占用,并请求锁定对方的资源,从而导致恶性循环的现象。
常见的解决死锁的方法
        如果不同程序会并发存取多个表, 尽量约定以相同的顺序访问表,可以大大降低死锁机会。
        在同一个事务中,尽可能做到一次锁定所需要的所有资源,减少死锁产生概率;
        对于非常容易产生死锁的业务部分,可以尝试使用升级锁定颗粒度,通过表级锁定来减少死锁产生的概率;
如果业务处理不好可以用分布式事务锁或者使用乐观锁
update tb_users set salary=? where id=1
update tb_users set salary=?,version=2 where id=1 and version=1 [version 是一个额外的列,用于记录当前行的版本号]
查询缓存
可以缓存 select 语句的查询结果,以浪费内存为代价换取高执行效率
这个下载版本可能会有不能启动的问题,请大家使用其它版本进行测试
配置参数 query_cache_type
        0 不开启
        1开启缓存,默认缓存所有 select ,如果需要不缓存则需要在 select 语句中添加 sql-no-cache 提示放弃缓存
        2开启缓存,默认都不缓存,需要在 sql 语句中添加 select sql-cache 主动缓存
需要添加 mysql 配置文件, windows my.ini Linux my.conf
query_cache_type = 1

 查看MySQL是否开启缓存

show variables like 'query_cache_type' ;

配置打开查询缓存大小

set global query_cache_size= 64 * 1024 * 1024 ; -- 配置查询缓存为 64M
show variables like 'query%' ;

 将查询结果进行

select sql_cache * from tb_users where ...;

重置缓存 

reset query cache ;

你可能感兴趣的:(mysql,数据库,java)