MySQL 的那些锁

更新日期: 2015-12-12 阅读次数: 9112 分类: MySQL

MySQL 锁的类型

shared locks (read locks):

Read locks on a resource are shared, or mutually nonblocking: many clients can read from a resource at the same time and not interfere with each other.

exclusive locks (write locks):

Write locks, on the other hand, are exclusive—i.e., they block both read locks and other write locks—because the only safe policy is to have a single client writing to the resource at a given time and to prevent all reads when a client is writing.

问题来了,既然 shared locks 名为共享的,而非独占的。那么她存在的意义何在?

在 StackOverflow 上找到了一个很好的解释, What's the difference between an exclusive lock and a shared lock?

归纳一下,shared locks 是为 exclusive locks 而存在的,即,只要还有 shared locks 存在,就无法设置 exclusive locks。防止写操作影响了当前正在进行的读操作。

锁的粒度

细分对共享资源的锁的粒度,是提高并发的好方法。

  • table lock: lowest overhead
  • row lock: greatest concurrency

但是,锁的粒度不是越细越好。因为获取锁,释放锁等操作越多,消耗的系统资源越多。需要在系统资源损耗与资源操作安全性之间找一个平衡点。

MySQL 的不同 storage engines 提供了不同的锁机制。注意,尽管不同的 storage engines 可以独立控制自己的锁机制。但是, MySQL 仍然会对锁机制进行控制。例如,无论是什么 storage engine,ALTER TABLE 操作永远都是 table lock。

InnoDB 和 XtraDB storage engine 提供了 row lock.

死锁

死锁是当两个或者多个事务在同一块资源上同时持有锁,并请求锁。

听起来是很别扭。这种情况出现在多个事务对多个资源的锁顺序不同上, 例如

Transaction #1

START TRANSACTION;
UPDATE StockPrice SET close = 45.50 WHERE stock_id = 4 and date = '2002-05-01';
UPDATE StockPrice SET close = 19.80 WHERE stock_id = 3 and date = '2002-05-02';
COMMIT;

Transaction #2

START TRANSACTION;
UPDATE StockPrice SET high = 20.12 WHERE stock_id = 3 and date = '2002-05-02';
UPDATE StockPrice SET high = 47.20 WHERE stock_id = 4 and date = '2002-05-01';
COMMIT;

当这两个事务都执行完了第一条更新,同时要执行第二条更新,就会发现资源被锁了,然后相互等待,造成死循环。

InnoDB 对于这种 circular dependencies,能自动检测到,并立即报错。

关于作者 🌱

我是来自山东烟台的一名开发者,有敢兴趣的话题,或者软件开发需求,欢迎加微信 zhongwei 聊聊, 查看更多联系方式