2012-04-23 39 views
6

Tôi nghĩ rằng phải có điều gì đó cơ bản tôi không hiểu về khóa cố vấn ở bưu điện. Nếu tôi nhập các lệnh sau trên máy khách dòng lệnh psql, hàm trả về đúng cả hai lần:Nhận khóa tư vấn ở bưu điện

SELECT pg_try_advisory_lock(20); --> true 
SELECT pg_try_advisory_lock(20); --> true 

Tôi mong rằng lệnh thứ hai sẽ trả về false, vì khóa đã được mua. Kỳ quặc, tôi làm được những điều sau đây, cho thấy rằng các khóa đã được mua lại hai lần:

SELECT pg_advisory_unlock(20); --> true 
SELECT pg_advisory_unlock(20); --> true 
SELECT pg_advisory_unlock(20); --> false 

Vì vậy, tôi đoán câu hỏi của tôi là, làm thế nào để có được một khóa tư vấn trong một cách mà dừng nó được mua lại một lần nữa?

+8

Từ cùng một phiên, bạn có thể nhận được cùng một khóa bao nhiêu lần tùy thích; nhưng bạn phải phát hành cùng một số lần hoặc đóng phiên trước khi một phiên khác có thể lấy khóa. – kgrittn

Trả lời

11

Điều gì xảy ra nếu bạn sẽ thử thực hiện việc này từ 2 phiên PostgreSQL khác nhau?

Khám phá thêm in the docs.

+2

Ah tôi hiểu rồi, vì vậy khi một phiên đã có khóa, nó có thể lấy lại, nhưng một phiên khác thì không. Cảm ơn! – foldl

3

Ấn tượng đầu tiên của tôi về khóa cố vấn tương tự. Tôi mong đợi truy vấn thứ hai (SELECT pg_tryadvisory_lock (20)) để trả về false quá (vì người đầu tiên có khóa). Nhưng truy vấn này chỉ xác nhận rằng một bigInt có giá trị 20 có khóa. Việc giải thích là tùy thuộc vào người dùng.

Hãy tưởng tượng ổ khóa tư vấn là bảng nơi bạn có thể lưu trữ giá trị và nhận khóa trên giá trị đó (thường là BigInt). Nó không có khóa rõ ràng và không có sự chuyển giao nào bị trì hoãn. Nó phụ thuộc vào bạn làm thế nào để giải thích và sử dụng kết quả - và nó không bị chặn.

Tôi sử dụng nó trong các dự án của mình với tùy chọn hai số nguyên. SELECT pg_try_advisory_lock (classId, objId) trong khi cả hai tham số là số nguyên.

Để làm cho nó làm việc với nhiều hơn một bảng chỉ cần sử dụng các OID của bảng như classid và id tiểu học (ở đây 17) như objId:

SELECT pg_try_advisory_lock((SELECT 'first_table'::regclass::oid)::integer, 17);

Trong ví dụ này "first_table" là tên của bảng và số nguyên thứ hai là id khóa chính (ở đây: 17).

Sử dụng tham số lớnInt cho phép phạm vi id rộng hơn, nhưng nếu bạn sử dụng nó với "second_table" hơn id 17 cũng bị khóa (vì bạn đã khóa số "17" chứ không phải liên quan đến một hàng cụ thể trong một cái bàn).

Tôi mất một thời gian để tìm ra điều đó, vì vậy hy vọng nó sẽ giúp hiểu được các hoạt động bên trong của các khóa cố vấn.

+0

Tôi không hiểu điều này .. bạn đề cập đến 'nhưng nếu bạn sử dụng nó với" second_table "hơn id 17 bị khóa cũng' cách id 17 sẽ bị khóa trong trường hợp trên với khóa tư vấn sau đây khi tôi sử dụng truy vấn sau 'SELECT pg_try_advisory_lock ((SELECT 'first_table' :: regclass :: oid) :: số nguyên, 17);' – Viren

Các vấn đề liên quan