锁分类

1.读锁(共享锁,读操作不受影响,别的会话有插入操作会处于阻塞状态) 写锁(排他锁,在写操作完成之前,会阻断其他读和写操作)
2.表锁和行级锁

1.表锁 偏读

myisam存储引擎,开销小,加锁快,锁力度大,发生锁冲突的概率最高,并发度最低
//手动加锁
lock table 表名称 read(write),表名称2 read(write),其他;
//查看表上加过的锁
show open tables;
//删除表锁
unlock tables;
//分析表锁定
show status like 'table%';
Variable_name | Value |
+----------------------------+-------+

| Table_locks_immediate | 112 |//产生表级锁定的次数,表示可以立即获取锁的查询次数,每立即获取锁值加1

| Table_locks_waited | 0 | //出现表级锁定争用而发生等待的次数(不能立即获取锁的次数,每等待一次锁值加1),此值高则说明存在着较严重的表级锁争用情况。

| Table_open_cache_hits | 0 |

| Table_open_cache_misses | 6 |//在打开表时,表缓存不存在的次数。

| Table_open_cache_overflows | 0 |

2.行锁 偏写

行锁偏向InnoDB存储引擎,开销大,加锁慢,会出现死锁,锁定粒度最小,发生锁冲突的概率最低,并发度也最高。
InnoDB与MYISAM的最大不同有两点:一是支持事务(TRANSACTION);二是采用了行级锁。
事务特性:原子性Atomicity,一致性Consistent,隔离性lsolation,持久性Durable
1.set autocommit=0;update ......;commit;
2.间隙锁
当我们用范围条件而不是相等条件检索数据,并请求共享或排他锁,Innodb会给符合条件的已有数据记录的索引加锁;对于键值在条件范围内但不存在的记录,叫做间隙(GAP);Innodb也会对这个间隙加锁,
危害:因为query执行过程中通过范围查找的话,他会锁定整个范围所有的索引值,即使这个键值并不存在。
行锁分析:
show status like 'innodb_row_lock%';

+-------------------------------+-------+

| Variable_name | Value |

+-------------------------------+-------+

| Innodb_row_lock_current_waits | 0 |当前正在等待锁定的数量

| Innodb_row_lock_time | 0 |从系统启动到现在锁定总时间长度

| Innodb_row_lock_time_avg | 0 |每次等待所花平均时间

| Innodb_row_lock_time_max | 0 |从系统启动到现在等待最长的一次所花时间

| Innodb_row_lock_waits | 0 |系统启动后到现在总共等待的次数 **

3.页面锁 偏写

开销和加锁时间界于表锁和行锁之间;会出现死锁;锁定粒度界于表锁和行锁之间,并发度一般

其他

共享锁(S):SELECT FROM table_name WHERE ... LOCK IN SHARE MODE。
排他锁(X):SELECT * FROM table_name WHERE ... FOR UPDATE。
InnoDB这种行锁实现特点:只有通过索引条件检索数据,InnoDB才使用行级锁,否则,InnoDB将使用表锁!

优化建议

1.尽可能让所有数据检索都通过索引来完成,避免无索引行锁升级为表锁
2.合理设计索引,尽量缩小锁的范围
3.尽可能减少检索条件,避免间隙锁
4.尽量控制事务大小,减少锁定资源量和时间长度
5.尽可能低级别事务隔离