Pg_trigger_depth () có tệ khi sử dụng để ngăn xếp tầng kích hoạt (đệ quy) không?


8

Tại sao lại pg_trigger_depth() = 0không tốt khi sử dụng (cho bất kỳ thứ gì khác ngoài gỡ lỗi) khi ngăn chặn tầng kích hoạt (đệ quy)?

Ai đó có thể cung cấp mã để chứng minh tại sao nó xấu?

Tôi đoán bởi vì nếu nhiều trình kích hoạt đang hoạt động trên cùng một dữ liệu cùng một lúc thì một điều kiện dừng kích hoạt sử dụng pg_trigger_depth() = 0sẽ dừng bất kỳ trình kích hoạt nào đứng thứ hai để thực hiện công việc.

Tôi nghĩ rằng nó sẽ là một giải pháp tốt cho câu hỏi này (của tôi) ở đây, nhưng tôi được nói khác:

Nghĩ rằng nó sẽ làm cho một câu hỏi hay.

Nó được cung cấp ở đây như là một giải pháp:

Tài liệu Postgres 9.3:

https://www.postgresql.org/docs/9.3/static/fifts-info.html

Câu trả lời:


1

Có, thật tệ khi khiến hành vi phụ thuộc vào pg_trigger_depth()

Có lẽ tôi ít ác cảm hơn với những tuyên bố về chăn, nhưng nó có thể làm gì tốt? Không có đối số tôi có thể thấy là tại sao bạn lại muốn một tính năng như vậy. Mục đích chính của cơ sở dữ liệu là đảm bảo tính toàn vẹn dữ liệu. Và theo như tôi có thể thấy, và tôi có thể sai, việc sử dụng như vậy luôn là một sự vi phạm tiềm tàng về tính toàn vẹn dữ liệu. Trong câu trả lời của @ Erwin, anh nói "nếu bạn quên" . Điểm đảm bảo tính toàn vẹn là loại bỏ khả năng đó. Nếu một tác nhân có thể nhớ tất cả mọi thứ và hiểu hậu quả và mã xung quanh chúng, bạn có thể có được tính toàn vẹn dữ liệu từ bất cứ điều gì .

Chúng ta hãy giới thiệu một vài thuật ngữ, trong lập trình, chúng ta có

  • "trạng thái" bao gồm mọi thứ màlập trình viên có quyền truy cập.
  • "bối cảnh thực hiện" bao gồm môi trường để thực thi.

Chúng tôi tiếp tục có một thuật ngữ cho một chức năng, không có trạng thái mà chúng tôi gọi đó là một chức năng thuần túy ,

Hàm luôn đánh giá cùng một giá trị kết quả được đưa ra cùng (các) giá trị đối số. Giá trị kết quả chức năng không thể phụ thuộc vào bất kỳ thông tin hoặc trạng thái ẩn nào có thể thay đổi trong khi tiến hành chương trình tiến hành hoặc giữa các lần thực hiện khác nhau của chương trình, cũng không thể phụ thuộc vào bất kỳ đầu vào bên ngoài nào từ các thiết bị I / O (thường là xem bên dưới).

Sự khác biệt cho độ tinh khiết rất hữu ích vì nó giúp loại bỏ bất kỳ gánh nặng phải nhớ bất cứ điều gì trên danh nghĩa của máy tính, hoặc các lập trình viên: f(x) = yluôn luôn đúng. Ở đây bạn đang vi phạm độ tinh khiết ở nơi tồi tệ nhất - cơ sở dữ liệu. Và, bạn đang thực hiện nó một cách phức tạp và dễ bị lỗi - làm cho bối cảnh thực thi nội bộ trở thành một điều có thể sờ thấy trong trạng thái của ứng dụng DB của bạn.

Tôi sẽ không muốn điều đó. Chỉ cần xem xét sự phức tạp bạn phải đệm tinh thần.

  • Table A's Trigger Acháy
    • Trigger Aluôn luôn phát hành DML Table B, bắn Trigger B.
      • Trigger Bcó điều kiện phát hành DML Table A, bắn Trigger A.
      • Trigger Bluôn luôn phát hành DML Table A, bắn Trigger A.
    • Trigger Acó điều kiện phát hành DML Table B, bắn Trigger B.
      • Trigger Bcó điều kiện phát hành DML Table A, bắn Trigger A.
      • Trigger Bluôn luôn phát hành DML Table A, bắn Trigger A.

Nếu điều đó có vẻ phức tạp, hãy nhớ rằng "có điều kiện" có thể được mở rộng hơn nữa thành "nó đã xảy ra, nhưng nó có thể không luôn luôn xảy ra""nó đã không xảy ra, nhưng nó có thể xảy ra ở nơi khác."

Để pg_trigger_depth()thậm chí hữu ích, bạn phải có một chuỗi các sự kiện phức tạp tương tự. Và, bây giờ, bạn muốn thực thi phụ thuộc vào nội dung thực thi trong chuỗi đó?

Tôi sẽ tránh điều này. Nếu hệ thống kích hoạt của bạn phức tạp như vậy, thì bạn đang chơi khoai tây nóng với một quả lựu đạn trong tủ một mình và dường như nó không có khả năng kết thúc tốt.


10

không phải là xấu khi sử dụng mỗi se (IMHO). Bạn chỉ cần nhận thức được ý nghĩa.

Tôi muốn làm điều đó pg_trigger_depth() < 1thay vì pg_trigger_depth() = 0, trên hiệu trưởng, nhưng điều đó không quan trọng ở đây. Chúng tôi đang nói về các kích hoạt như:

CREATE TRIGGER my_trigger
AFTER INSERT ON my_tbl
FOR EACH ROW
WHEN (pg_trigger_depth() < 1)
EXECUTE PROCEDURE my_trigger_func();

Nếu sau này bạn thêm các kích hoạt sẽ lần lượt kích hoạt kích hoạt của bạn, thay vào đó sẽ không có gì xảy ra. Kích hoạt của bạn chỉ phản ứng với các sự kiện không kích hoạt. Tùy thuộc vào thiết lập của bạn, đây có thể là chính xác những gì bạn muốn - hoặc một loại bẫy, nếu bạn quên điều này và sau đó thêm nhiều kích hoạt sẽ lần lượt kích hoạt trình kích hoạt này. Bạn đang thay đổi hành vi mặc định. Hãy chắc chắn để tài liệu này rõ ràng.

Xin lưu ý rằng pg_trigger_depth()đếm bất kỳ trình kích hoạt nào , không chỉ cùng một trình kích hoạt để ngăn đệ quy, vì vậy điều kiện này cũng ngăn chặn trình kích hoạt bắn nếu được gọi từ bất kỳ trình kích hoạt nào khác.
Hướng dẫn sử dụng:

mức độ lồng nhau hiện tại của trình kích hoạt PostgreSQL (0 nếu không được gọi, trực tiếp hoặc gián tiếp, từ bên trong trình kích hoạt)

Liên quan:

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.