引用:https://mbd.baidu.com/newspage/data/dtlandingsuper?nid=dt_5200837128726562540&sourceFrom=search_b
1. 乐观锁
- 定义:乐观锁假设大多数情况下不会有冲突,因此在操作时不加锁,而是在提交数据时检测冲突,若有冲突则重试。
- 作用:通过减少锁的使用,提高并发性能。
- 应用场景:读取多、写入少的场景,如数据初始化或批量导入等。
- 示例:使用版本号控制,在更新时检查版本号是否一致,若不一致则说明有冲突。
2. 悲观锁
- 定义:悲观锁认为每次操作都会发生冲突,因此在操作前先加锁,阻止其他线程访问。
- 作用:通过锁定资源,确保资源独占性,避免并发修改。
- 应用场景:高并发环境中,频繁修改数据的场景,如订单生成、支付等。
- 示例:数据库事务中的 SELECT ... FOR UPDATE 语句就会使用悲观锁。
3. 共享锁/读锁
- 定义:共享锁允多个事务同时读取一个资源,但不允许修改。
- 作用:防止并发修改,允许多个读操作同时进行,提高并发读取性能。
- 应用场景:多个用户查询同一数据时,无需互相阻塞。
- 示例:SQL查询操作 SELECT 一般会使用共享锁。
4. 互斥锁/写锁/排它锁/独占锁
- 定义:互斥锁只允许一个线程访问资源,其他线程在锁释放前无法访问该资源。
- 作用:防止多个线程同时修改资源,保证数据一致性。
- 应用场景:写操作,避免多个线程同时写入造成的数据不一致。
- 示例:数据库更新操作 UPDATE 或 DELETE 通常会使用互斥锁。
5. 行锁定与表锁定
- 行锁定:数据库级别的锁,锁定单行记录,避免多个事务同时修改同一行数据。
- 作用:减少锁的范围,提高并发访问能力。
- 应用场景:数据库系统中多用户同时访问同一表但不同数据行时。
- 示例:MySQL 的 InnoDB 引擎支持行锁。
- 表锁定:锁定整个表,阻止其他线程对表的读写操作。
- 作用:保证整个表的数据一致性,但会降低并发性能。
- 应用场景:当需要对表进行大规模修改或删除时,如重建表索引等操作。
- 示例:MySQL 的 MyISAM 存储引擎默认使用表锁。
6. 事务的隔离级别与数据库锁的对应关系
读未提交(Read Uncommitted)
通过共享锁(S锁)实现,允许事务读取数据时加锁,但允许其他事务继续读写同一数据。此隔离级别下,事务可能读取到其他未提交的事务数据,导致脏读风险。 [1MySQL默认隔离级别为读已提交。 12
读已提交(Read Committed)
多数数据库默认隔离级别,通过排他锁(X锁)实现。每次读取数据时加锁,但仅阻止其他事务修改当前数据,允许其他事务读取。此级别避免脏读,但可能出现不可重复读。 12
可重复读(Repeatable Read)
MySQL默认隔离级别,通过行锁(X锁)实现。事务开始时锁定所有涉及数据行的排他锁,防止其他事务修改或删除数据。此级别避免不可重复读,但可能发生幻读。 12
序列化(Serializable)
最高隔离级别,通过行锁(X锁)实现。锁定涉及数据行的排他锁,并要求其他事务等待锁释放。此级别完全避免幻读,但可能导致长时间锁定资源。 12
不同数据库系统可能通过不同组合的锁机制实现相同隔离级别,例如Oracle通过多版本并发控制(MVCC)而非传统锁机制实现可重复读