MySQL索引(三)

70 阅读3分钟

一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第21天,点击查看活动详情

锁是用来解决多个任务(线程、进程)在并发访问同一共享资源时带来的数据安全问题。虽然使用锁解决了数据安全问题,但是会带来性能的影响,频繁使用锁的程序的性能是必然很差的。

对于数据管理软件MySQL来说,必然会到任务的并发访问。那么MySQL是怎么样在数据安全和性能上做权衡的呢?--MVCC设计思想。

锁的分类

从性能上划分:乐观锁和悲观锁

  • 悲观锁:悲观的认为当前的并发是非常严重的,所以在任何时候操作都是互斥的。保证了线程的安全,但牺牲了并发性。--总有刁民想害朕
  • 乐观锁:乐观的认为当前并发并不严重,因此对于读的情况,大家都可以进行,但是对于写的情况,在进行上锁。以CAS自旋锁,在某种情况下性能是ok的,但是频繁自旋会消耗很大的资源。---天网恢恢疏而不漏 - version 版本号

从数据的操作细粒度上划分:表锁和行锁

  • 表锁:对整张表上锁。
  • 行锁:对表中的某一行上锁。

从数据库的操作类型上划分:读锁和写锁

这两中锁都是属于悲观锁

  • 读锁(共享锁):对于同一行数据进行“读”来说,是可以同时进行但是写不行。
  • 写锁(排他锁):再上了写锁之后,及释放写锁之前,在整个过程是不能进行任何的其他并发操作(其他任务的读和写是都不能进行的)。

表锁

对整张表进行上锁。MyISAM存储引擎是天然支持表锁的,也就是说在MyISAM的存储引擎的表中如果出现并发的情况,将会出现表锁的效果,MyISAM不支持事务。

在innoDB中上一下表锁:

#对一张表上读锁/写锁格式
lock table 表名 read/write;
#例子
lock table tb_book read;
#查看当前会话对所有表的上锁情况
show open tables;

读锁:其他任务可以进行读,但是不能进行写

写锁:其他任务不能进行读和写。

事务的特性

ACID

  • 原子性:一个事务是一个最小的操作单位(原子),多条sql在一个事务中要么同时成功,要么同时失败
  • 一致性:事务提交之前和回滚之后的数据是一致的
  • 持久性:事务一旦提交,对数据的影响是持久的
  • 隔离性:多个事务在并发访问下,提供了一套隔离机制,不同的隔离级别会有不同的并发效果。在事务里不会被其他事务所破坏

事务的隔离界别

  • read uncommitted(读未提交):在一个事务中读取到另一个事务还没提交到的数据--脏读。
  • read committed(读已提交):已经解决了脏读问题,在一个事务中只会读取另一个事务已提交的数据,这种情况会出现不可重复读的问题。就是:在事务中重复读数据,数据的内部不一样的。
  • repeatabel read(可重复读):在一个事务每次读取的数据都是一致的,不会出现脏读和不可重复读的问题。会出现许虚读的问题。
  • Serializable:可串行化 脏读、不可重复读、虚读(幻读)