Oracle - Có cách nào để xem các thay đổi không được cam kết đối với một bảng cụ thể không?


24

Tôi đang gỡ lỗi thông qua một quy trình hàng loạt hiện đang thực hiện rất nhiều câu lệnh DML, nhưng không thực hiện cam kết ngay lập tức. Sẽ thật tuyệt khi có thể xem các thay đổi "đang chờ xử lý" từ một phiên khác trong khi giao dịch không được cam kết. Điều này có thể không?

Thí dụ:

Insert into table myTable (col1, col2) values ("col1", "col2");

--Somehow view the pending transaction maybe by system view?....

...other DML statements....

commit;

Có nhiều hơn một cách để làm điều đó. Ví dụ: các câu lệnh SQL ở đây có thể giải quyết: ducquoc.wordpress.com/2012/07/14/oracle-uncommited-changes chúc may mắn,

Câu trả lời:


18

Có một vài cách tiếp cận khác nhau tùy thuộc vào chi tiết của quy trình hàng loạt của bạn và lý do tại sao bạn đang cố gắng xem các thay đổi không được cam kết.

1) Trình quản lý không gian làm việc của Oracle là một công cụ ban đầu được thiết kế để cho phép mọi người phát triển các ứng dụng Không gian có tương đương với các giao dịch cực kỳ dài (tức là các giao dịch có thể cần nhiều ngày hoặc nhiều tuần để tìm ra nơi chạy một đường ống trong một giao dịch ). Quá trình hàng loạt của bạn có thể tạo ra một không gian làm việc mới (về mặt logic như tạo một giao dịch mới), thực hiện bất kỳ thay đổi nào nó muốn trong không gian làm việc đó trong khi cam kết bất cứ khi nào nó muốn. Trong một phiên riêng biệt, bạn sẽ không thấy bất kỳ thay đổi nào được cam kết cho đến khi bạn vào không gian làm việc của quy trình hàng loạt. Khi quá trình xử lý hàng loạt kết thúc, nó có thể hợp nhất không gian làm việc của nó trở lại không gian làm việc trực tiếp, tương đương với việc thực hiện giao dịch.

2) Gói DBMS_XA có thể được sử dụng để cho phép bạn "thực hiện" giao dịch từ phiên này sang phiên khác và cho phép một phiên kết nối với giao dịch được bắt đầu bởi phiên khác. Đây là một gói khá khó hiểu đang được sử dụng, nhưng có một ví dụ hay về việc sử dụng nó trong Thử thách PL / SQL (bạn có thể cần một tài khoản miễn phí để truy cập vào nó) gần đây.

3) Nếu bạn chỉ đang cố gắng xem trạng thái của quy trình lô thay vì xem dữ liệu thực tế, quy trình lô có thể ghi thông tin đăng nhập bằng các giao dịch tự trị mà sau đó bạn có thể truy vấn từ phiên khác. Hoặc bạn có thể sử dụng gói DBMS_APPLICATION_INFO để ứng dụng của bạn cập nhật các thuộc tính khác nhau trong V $ SESSION và / hoặc V $ SESSION_LONGOPS để bạn có thể theo dõi trạng thái tải từ phiên khác.


10

chỉnh sửa: điều này đã được viết trước khi câu hỏi được làm rõ

Bạn có thể sử dụng các truy vấn hồi tưởng để xem bảng mà không có dữ liệu không được cam kết của riêng bạn .

Xem xét:

SQL> CREATE TABLE my_table
  2  AS SELECT ROWNUM ID FROM dual CONNECT BY LEVEL <= 5;

Table created

SQL> INSERT INTO my_table VALUES (6);

1 row inserted

Để thấy sự khác biệt giữa bảng với giao dịch của tôi và bảng mà người khác nhìn thấy, tôi có thể phát hành:

SQL> SELECT * FROM my_table
  2  MINUS
  3  SELECT * FROM my_table AS OF TIMESTAMP (systimestamp);

        ID
----------
         6

2
@jack: Không rõ OP có muốn xem dữ liệu không được cam kết ngoài phiên hay không (tập lệnh giả có thể trong một phiên). Câu trả lời của tôi sẽ chỉ hoạt động để xem các sửa đổi đang chờ xử lý của chính mình đối với một bảng.
Vincent Malgrat

bạn nói đúng, xin lỗi Câu trả lời chính xác.
Jack Douglas

8

Có - LogMiner có thể làm điều này. Trong thực tế, nếu bạn chỉ muốn các giao dịch được cam kết, bạn phải lọc cụ thể đầu ra! Và có TABLE_NAMEtrong V$LOGMINER_CONTENTS, đó là cách bạn sẽ nhìn vào một bảng duy nhất.



5

Không có phương pháp trực tiếp; bạn sẽ phải phân tích các bản ghi (như được đề cập trong câu trả lời khác) hoặc sử dụng các phương pháp thay thế để xem những gì đang xảy ra trong một quy trình dài.

Cá nhân, tôi khuyên bạn nên sử dụng các giao dịch tự trị để kích hoạt tính năng này - không phải trên chính giao dịch, mà là một cơ chế ghi nhật ký cho bạn biết những gì đang diễn ra. Ví dụ: bạn có thể có PROCEDURE LONG_ACTION gọi PROCEDURE WRITE_LOG_ENTRY (được định nghĩa là giao dịch tự trị) sẽ ghi VARCHAR2 sang bảng khác. Các giao dịch tự động KHÔNG can thiệp vào giao dịch hiện tại của bạn (từ góc độ LOGICS; hãy cẩn thận với các tác động tiềm năng đến hiệu suất) và vì vậy bạn có thể thấy những gì đang diễn ra thông qua các mục đăng nhập của mình bất kể CAM KẾT hoặc ROLLBACK trong giao dịch hiện tại của bạn. Điều đó nói rằng, bạn có thể làm điều đó với một tuyên bố DML lớn; bạn phải sử dụng một vòng lặp.

Xem xét:

TABLE LOG_ENTRIES defined as
    activity_date  date,
    log_entry varchar2(2000)

TABLE BIG_JOB (definition doesn't really matter)

PROCEDURE WRITE_LOG_ENTRY
                        ( str VARCHAR2 )
IS
    PRAGMA AUTONOMOUS_TRANSACTION;
BEGIN
    INSERT INTO LOG_ENTRIES VALUES ( SYSDATE, str );
    COMMIT;
END;

PROCEDURE LONG_ACTION IS
    c NUMBER;
BEGIN
    FOR r IN ( SELECT * FROM BIG_JOB )
    LOOP
       c := c + 1;
       UPDATE BIG_JOB z
          SET fld = hairy_calculation
        WHERE z.rowid = r.rowid;
       IF MOD(c,500) = 0 THEN
           WRITE_LOG_ENTRY ( c || ' rows processed.' );
       END IF;
    END LOOP;
    COMMIT;
END;

Với những điều trên, bạn sẽ nhận được một mục nhật ký cho mỗi 500 hàng được xử lý bất kể thành công của hành động dài. Nếu bạn cần một bản sao chính xác của dữ liệu để xem nó đang hoạt động, tôi khuyên bạn nên tạo một bảng trùng lặp và gọi một thủ tục sẽ sao chép dữ liệu (thủ tục là một giao dịch tự trị). Sau đó nuke dữ liệu sau thực tế. (Không cần sao chép.)

Hơn nữa, nếu điều này là cho mục đích gỡ lỗi, tôi khuyên bạn nên loại bỏ hoặc giảm đáng kể nhu cầu đăng nhập như vậy khi mọi thứ đã được thử nghiệm. Và, như mọi khi, kiểm tra, thử nghiệm, kiểm tra trên hệ thống của riêng bạn để xác minh cách mọi thứ sẽ hoạt động. (Xem bình luận từ Niall để biết ví dụ hay về cách đăng nhập có thể ảnh hưởng mạnh đến hiệu suất.)

(Cuối cùng, vì tôi đã bỏ qua việc đề cập đến nó trước đây: hãy cẩn thận các giao dịch tự trị. Hãy hiểu chúng đầy đủ trước khi thực hiện và đừng sử dụng chúng "chỉ vì". Chúng có thể được sử dụng theo hàng triệu cách không chính xác (ví dụ: ATTEMPT để tránh một lỗi đột biến trong trình kích hoạt), vì vậy, tốt nhất là luôn luôn tìm các giải pháp thay thế, nếu có thể. Nếu không thể, hãy tiến hành thận trọng. Đăng nhập trong các ops chạy dài luôn là một trường hợp khá an toàn (bỏ qua vấn đề về hiệu suất), nhưng đừng vội áp dụng nó vào các mục đích sử dụng khác mà không biết hậu quả.)


1
Thông báo trước khi kết thúc đề xuất này được khám phá thêm trong phản hồi dài của tôi (có mã) tại orawin.info/blog/2011/09/06/advice-from-the-iNET . Tóm lại, việc áp dụng phương pháp này có thể ảnh hưởng nghiêm trọng và bất lợi đến mã vốn đã chậm.
Niall Litchfield

1
@Niall Litchfield, Như mọi khi, khi nhận lời khuyên từ internet, người ta phải luôn luôn kiểm tra, thử nghiệm, kiểm tra. Khi được đề cập rằng giao dịch tự trị không ảnh hưởng đến giao dịch, tôi đã đề cập đến thực tế là nó không CAM KẾT hay ROLLsBACK giao dịch hiện tại của bạn; do đó, theo nghĩa logic, nó không ảnh hưởng gì đến giao dịch hiện tại của bạn. Tất nhiên, Oracle đã làm những điều hậu trường để khiến mọi thứ hoạt động, điều đó có thể có nghĩa là các vấn đề về hiệu suất, từ quan điểm chỉ giao dịch, giao dịch tự trị không ảnh hưởng đến trạng thái giao dịch hiện tại của tôi.
Kerri Shotts

@Niall Litchfield, Tất cả những gì đã nói, các giao dịch tự trị có một số vấn đề riêng của họ (một trong số đó là mọi người cố gắng sử dụng chúng để đi xung quanh một bảng đột biến), và vì vậy tôi khuyên bạn nên thận trọng và thận trọng, và CHỈ với sự hiểu biết những gì đang xảy ra.
Kerri Shotts

3

Không khả dụng trong 10g, nhưng DBMS_XA có thể cho phép giao dịch vượt qua nhiều phiên. Sử dụng phiên thứ hai có thể thấy những gì đang xảy ra trong giao dịch


3

Ngoài các thông tin khác ở đây, một số cách bổ sung để gửi thông tin về giao dịch không được cam kết sẽ là gửi email hoặc viết vào tệp văn bản.

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.