Cam kết có cần thiết sau khi hoạt động DML trong Chức năng / Quy trình không?


20

Tôi tự hỏi để biết có cần thiết phải viết cam kết sau khi chèn / xóa / cập nhật trong chức năng / thủ tục không?

Thí dụ:

create or replace function test_fun
return number is
begin
   delete from a;
   return 0;
end;

hoặc thủ tục

create or replace procedure aud_clear_pro
as
begin
   delete from a;
end;

nó có cần cam kết sau khi xóa không?

Không thể hiểu được tình huống sau đây:

  1. Nếu tôi gọi hàm / thủ tục từ cửa sổ SQL thì nó yêu cầu cam kết

    nhưng

  2. Nếu tôi lên lịch chức năng / thủ tục bằng cách sử dụng dbms_scheduler và chạy công việc, xóa câu lệnh sẽ tự động được cam kết.

    TẠI SAO?

Câu trả lời:


24

Nói chung, thủ tục không nên cam kết. Những loại quyết định kiểm soát giao dịch đó nên được để lại cho mã cấp cao hơn để biết khi nào một giao dịch logic thực sự hoàn tất. Nếu bạn cam kết bên trong một thủ tục được lưu trữ, bạn đang giới hạn khả năng sử dụng lại bởi vì người gọi muốn các thay đổi mà thủ tục thực hiện là một phần của giao dịch lớn hơn có thể chỉ cần gọi thủ tục trực tiếp.

Nếu bạn gọi một thủ tục một cách tương tác, bạn sẽ phải cam kết rõ ràng hoặc hoàn trả giao dịch vì Oracle không biết bạn có ý định gọi thủ tục là giao dịch hợp lý hay nếu bạn có ý định soạn một giao dịch lớn hơn liên quan đến nhiều cuộc gọi thủ tục. Nếu bạn sử dụng dbms_scheduler, dbms_schedulergiả sử rằng một công việc là một giao dịch hợp lý và cam kết khi kết thúc công việc giả định rằng nó đã thành công ( dbms_jobthực hiện điều tương tự).

Các chức năng không nên thao tác dữ liệu ở vị trí đầu tiên. Hàm thao tác dữ liệu không thể được gọi từ câu lệnh SQL (chặn trường hợp góc trong đó chính hàm được khai báo để sử dụng giao dịch tự trị gần như không bao giờ phù hợp). Điểm chung của việc có cả hai hàm và thủ tục là các hàm có thể được nhúng trong các câu lệnh SQL và có thể được cấp tự do hơn cho người dùng vì chúng không thay đổi bất kỳ dữ liệu nào.


1
Có phải trong Oracle người gọi không thể bắt đầu một giao dịch ràng buộc các cuộc gọi thủ tục? Trong SQL Server, bạn có thể cam kết bên trong thủ tục, nhưng nếu người gọi đã mở một giao dịch trước khi gọi thủ tục đó, không có gì được cam kết cho đến khi người gọi cũng cam kết.
Nick Chammas

4
@NickChammas - Oracle không có khái niệm về giao dịch lồng nhau, không. Nếu thủ tục cam kết, mọi thứ người gọi đã thực hiện cho đến thời điểm đó sẽ cam kết. Người gọi luôn bắt đầu một giao dịch ngầm với câu lệnh đầu tiên của mình (cho dù đó là cuộc gọi thủ tục hay điều gì khác), vì vậy nó phải luôn luôn tùy thuộc vào người gọi để kết thúc giao dịch.
Hang Justin

@JustinCave Trong khi đó là sự thật, đừng quên các giao dịch tự trị.
Phil

@Phil - Đúng, nhưng đó là một động vật rất khác. Một giao dịch tự trị không thể thấy các thay đổi không được cam kết thực hiện bởi người gọi và không thể được người gọi quay lại, do đó, rất khó có thể có bất kỳ điều gì khác ngoài thủ tục đăng nhập phải được tuyên bố là sử dụng giao dịch tự trị.
Hang Justin

4

Để trả lời câu hỏi của bạn; TẠI SAO?

Có lẽ bạn đã biết điều này từ bây giờ vì bài viết đã 2 tuổi. Nhưng tôi sẽ trả lời cho hồ sơ.

Lý do # 1 yêu cầu một cam kết và # 2 không phải là vì cài đặt cơ sở dữ liệu mặc định trong Oracle là để thực hiện giao dịch khi phiên kết thúc. Nếu bạn đang ở sqlplus và chạy mã của mình theo cách thủ công, nó sẽ không cam kết giao dịch ngay lập tức. Nếu bạn phát hành một cam kết rõ ràng HOẶC bạn đăng xuất khỏi sqlpus, thì giao dịch sẽ cam kết.

Lý do tại sao bạn nhận được một cam kết tự động trên # 2 là vì nó tạo ra một phiên để chạy tập lệnh của bạn. Khi hoàn thành, nó sẽ tự động đăng xuất, điều này sẽ gây ra một cam kết tự động.

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.