MySQL - 常见的锁机制

MySQL中常见的锁机制有以下几种:共享锁(Shared Lock):共享锁也被称为读锁,它允许多个...

MySQL中常见的锁机制有以下几种:

共享锁(Shared Lock):

共享锁也被称为读锁,它允许多个会话同时读取同一资源,但不允许有其他会话持有排他锁。共享锁可以并发地存在,不会相互阻塞。共享锁可以防止其他会话对被锁定资源进行修改,但允许其他会话获得相同的共享锁。

 

共享锁可以通过以下方式实现:

SELECT语句中使用FOR SHARE或LOCK IN SHARE MODE子句,例如:SELECT * FROM table_name FOR SHARE;

事务中使用SELECT ... FOR SHARE语句,例如:

START TRANSACTION;
SELECT * FROM table_name WHERE ... FOR SHARE;
...
COMMIT;

 

排他锁(Exclusive Lock)(也叫行锁):

排他锁也被称为写锁,它用于防止其他会话读取或修改被锁定资源。只有一个会话可以持有排他锁,其他会话无法同时获取相同的共享锁或排他锁。排他锁可以防止其他会话同时读取或修改资源,确保资源的独占性。

排他锁可以通过以下方式实现:

SELECT、INSERT、UPDATE、DELETE语句的默认行为会自动获取排他锁。

事务中使用SELECT ... FOR UPDATE语句,例如:

使用排他锁时,其他除不带“for update” 的 select 查询可以获取到数据,其他数据读写均需要等待commit后才能实现读写

START TRANSACTION;
SELECT * FROM table_name WHERE ... FOR UPDATE;
...
COMMIT;

 

thinkPHP 使用

Db::startTrans();

Db::where()->lock(true)->find();

// do some thing

if(true){
    Db::commit();
}else{
    Db::rollback();
}

另:

在MySQL中,如果一个会话获得了行锁,其他会话可以通过以下两种方式处理:

等待锁释放:

默认情况下,其他会话会等待行锁被释放,然后再继续执行。当一个会话持有排他锁时,其他会话请求获取该行的共享锁或排他锁时会被阻塞。当排他锁被释放后,请求的会话将获得锁并继续执行。

超时断开:

在MySQL的配置中,可以设置等待行锁的超时时间。如果等待超时,会话将会自动被断开,释放锁资源,然后报错返回。

要注意的是,默认情况下等待时间是无限的(即不会超时),这可能导致其他会话长时间等待。为了避免死锁或长时间的阻塞,可以在配置中设置合适的等待超时时间,例如通过innodb_lock_wait_timeout参数进行配置。

另外,如果你使用事务,在事务中请求行锁时,MySQL会自动处理锁请求的等待和超时。如果事务等待超时,MySQL会自动回滚事务,并将错误返回给应用程序。

综上所述,MySQL默认情况下会等待行锁的释放,但需要注意设置合适的等待超时时间以及处理死锁情况,以确保系统的并发性能和稳定性。

 

 

 

记录锁(Record Lock):

记录锁是一种行级锁,用于保护表中的行,防止其他会话修改或删除该行。多个记录锁可以并发地存在,只要它们没有冲突(即没有共享相同的行)。记录锁是自动获得的,通过在SQL操作(例如UPDATE或DELETE)中使用WHERE子句指定条件来创建。

 

记录锁是自动获得的,可以通过以下方式实现:

执行SQL操作(例如UPDATE或DELETE)时,通过WHERE子句指定条件,例如:UPDATE table_name SET ... WHERE ...;

在需要保持锁的同时,设置事务的隔离级别为SERIALIZABLE。

 

隐式锁(Implicit Lock):

隐式锁是MySQL内部在执行特定操作时自动加上的锁,不需要显式地指定。例如,在使用INSERT或UPDATE等语句修改表时,MySQL会自动对相关的行加上适当的排他锁,避免多个会话同时修改相同的行。

 

表锁(Table Lock):

表锁是MySQL中一种粗粒度的锁机制,它用于锁定整个表而不是特定的行。当一个会话持有表锁时,其他会话无法同时获取相同表的共享锁或排他锁。表锁适用于需要锁定整个表的操作,但可能会对并发性能产生较大影响,因为其他会话无法并行操作相同的表。

 

表锁可以通过以下方式实现:

LOCK TABLES语句用于显式锁定一个或多个表,例如:

LOCK TABLES table_name READ;
...
UNLOCK TABLES;

在事务中,可以使用LOCK TABLES语句锁定表,或者设置事务的隔离级别为SERIALIZABLE。

 

这些锁机制可以通过合理的设计和使用,保证数据库中数据的一致性和完整性,并提供适当的并发控制。在使用锁时,需要根据具体的业务需求和并发访问模式进行选择和优化,以确保系统的性能和稳定性。

 

评论