English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية

PostgreSQL 락(락)

锁主要是为了保持数据库数据的一致性,可以阻止用户修改一行或整个表,一般用在并发较高的数据库中。

在多个用户访问数据库的时候若对并发操作不加控制就可能会读取和存储不正确的数据,破坏数据库的一致性。

数据库中有两种基本的锁:排它锁(Exclusive Locks)和共享锁(Share Locks)。

如果数据对象加上排它锁,则其他的事务不能对它读取和修改。

如果加上共享锁,则该数据库对象可以被其他事务读取,但不能修改。

LOCK 命令语法

LOCK 命令基础语法如下:

LOCK [ TABLE ]
name
 IN
lock_mode
  • name: 要锁定的现有表的名称(可选模式限定)。如果只在表名之前指定,则只锁定该表。如果未指定,则锁定该表及其所有子表(如果有)。

  • lock_mode: 锁定模式指定该锁与哪个锁冲突。如果没有指定锁定模式,则使用限制最大的访问独占模式。可能的值是:ACCESS SHARE,ROW SHARE, ROW EXCLUSIVE, SHARE UPDATE EXCLUSIVE, SHARE,SHARE ROW EXCLUSIVE,EXCLUSIVE,ACCESS EXCLUSIVE。

락을 얻으면, 락은 현재 트랜잭션의 나머지 시간 동안 유지됩니다. 테이블을 해락하는 명령이 없으며, 락은 항상 트랜잭션 종료 시 해제됩니다.

死锁

두 트랜잭션이 서로의 작업 완료를 기다리면서 서로 맞서게 되면死锁(deadlock)이 발생할 수 있습니다. PostgreSQL는 이를 감지하고 롤백으로 끝내지만, 여전히 불편합니다. 이 문제를 방지하기 위해 애플리케이션을 동일한 순서로 객체를 잠금하는 것을 보장해야 합니다.

상담 락

PostgreSQL는 애플리케이션 정의 의미를 가진 락을 생성하는 방법을 제공합니다. 이를 상담 락이라고 합니다. 시스템이 그들을 강제로 사용하지 않기 때문에, 올바른 사용은 애플리케이션에 따릅니다. 상담 락은 MVCC 모델에 맞지 않는 락 전략에 매우 유용합니다.

예를 들어, 락을 사용하는 일반적인 목적 중 하나는 "평면 파일" 데이터 관리 시스템에서 타입적 보수적인 락 전략을 모의하는 것입니다. 테이블에 저장된 기호는 같은 목적을 위해 사용될 수 있지만, 락을 통한 알림은 테이블 부풀림을 피하고, 세션 종료 시 서버에서 자동으로 정리됩니다.

온라인 예제

COMPANY 테이블 생성(COMPANY SQL 파일 다운로드 ),데이터 내용은 다음과 같습니다:

w3codeboxdb# select * from COMPANY;
 id | name  | age | address   | salary
----+-------+-----+-----------+--------
  1 | Paul  |  32 | California|  20000
  2 | Allen |  25 | Texas     |  15000
  3 | Teddy |  23 | Norway    |  20000
  4 | Mark  |  25 | Rich-Mond |  65000
  5 | David |  27 | Texas     |  85000
  6 | Kim   |  22 | South-Hall|  45000
  7 | James |  24 | Houston   |  10000
(7 rows)

아래의 예제는 w3codeboxdb 데이터베이스의 COMPANY 테이블은 ACCESS EXCLUSIVE 모드로 잠금되었습니다.

LOCK 문은 트랜잭션 모드에서만 작동합니다.

w3codeboxdb=#BEGIN;
LOCK TABLE company1 IN ACCESS EXCLUSIVE MODE;

위의 작업은 다음과 같은 결과를 얻습니다:

LOCK TABLE

위의 메시지는 테이블이 트랜잭션 종료까지 잠금되었음을 나타내며, 트랜잭션을 완료하려면 반드시 롤백하거나 트랜잭션을 커밋해야 합니다.