it-swarm-id.com

Oracle - Adakah cara untuk melihat perubahan yang tidak dikomit ke tabel tertentu?

Saya sedang debugging melalui proses batch saat ini yang melakukan banyak pernyataan DML, tetapi tidak langsung melakukan komit. Alangkah baiknya untuk dapat melihat perubahan "yang tertunda" dari sesi lain saat transaksi tidak dilakukan. Apakah ini mungkin?

Contoh:

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

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

...other DML statements....

commit;
24
contactmatt

Ada beberapa pendekatan berbeda tergantung pada detail proses batch Anda dan mengapa Anda mencoba melihat perubahan yang tidak dikomit.

1) Oracle Workspace Manager adalah alat yang pada awalnya dirancang untuk memungkinkan orang mengembangkan aplikasi Spatial untuk memiliki setara dengan transaksi yang sangat berjalan lama (yaitu transaksi yang mungkin memerlukan beberapa hari atau minggu manusia mencari tahu di mana untuk menjalankan pipa dalam satu transaksi). Proses batch Anda dapat membuat ruang kerja baru (yang secara logis seperti membuat transaksi baru), membuat perubahan apa pun yang diinginkan di ruang kerja itu sambil melakukan kapan pun diinginkan. Dalam sesi terpisah, Anda tidak akan melihat perubahan yang dilakukan sampai Anda memasuki ruang kerja proses batch. Ketika proses batch selesai, itu bisa menggabungkan ruang kerjanya kembali ke ruang kerja langsung yang setara dengan melakukan transaksi.

2) The paket DBMS_XA dapat digunakan untuk memungkinkan Anda "menyerahkan" transaksi dari satu sesi ke sesi lainnya dan untuk memungkinkan satu sesi untuk terhubung ke transaksi yang dimulai oleh sesi lain. Ini adalah paket yang cukup tidak jelas untuk digunakan, tetapi ada contoh yang bagus untuk menggunakannya di PL/SQL Challenge (Anda mungkin perlu akun gratis untuk mengaksesnya) baru-baru ini.

3) Jika Anda hanya mencoba melihat status proses batch daripada melihat data aktual, proses batch dapat menulis informasi logging menggunakan transaksi otonom yang kemudian dapat Anda query dari sesi lain. Atau Anda dapat menggunakan paket DBMS_APPLICATION_INFO untuk meminta aplikasi Anda memperbarui berbagai atribut dalam V $ SESSION dan/atau V $ SESSION_LONGOPS sehingga Anda dapat memantau status beban dari sesi lain.

18
Justin Cave

sunting: ini ditulis sebelum pertanyaan diklarifikasi

Anda bisa menggunakan kueri kilas balik untuk melihat tabel tanpa milik Anda data yang tidak dikomit.

Mempertimbangkan:

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

Untuk melihat perbedaan antara tabel dengan transaksi saya dan tabel seperti yang terlihat oleh orang lain saya bisa mengeluarkan:

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

        ID
----------
         6
10
Vincent Malgrat

Apa yang Oracle tidak miliki adalah mode isolasi tanpa komitmen baca . Dengan kata lain Anda tidak akan dapat meminta data yang tidak dikomit dalam transaksi lain.

Ada cara untuk mendapatkan informasi dari transaksi yang berjalan lama - yang tidak disebutkan sejauh ini adalah transaksi otonom (yang harus digunakan dengan hati-hati)

Ya - LogMiner dapat melakukan ini. Bahkan, jika Anda hanya ingin melakukan transaksi, Anda harus secara khusus filter output! Dan ada TABLE_NAME di V$LOGMINER_CONTENTS, itulah bagaimana Anda akan melihat satu tabel.

8
Gaius

Tidak ada metode langsung; Anda harus memilah-milah log (seperti yang disebutkan dalam jawaban lain), atau menggunakan metode alternatif untuk melihat apa yang terjadi dalam proses jangka panjang.

Secara pribadi, saya sarankan menggunakan transaksi otonom untuk mengaktifkan fitur ini - bukan pada transaksi itu sendiri, tetapi sebagai mekanisme pencatatan yang memberi tahu Anda apa yang sedang terjadi. Misalnya, Anda bisa meminta PROSEDUR LONG_ACTION menghubungi PROCEDURE WRITE_LOG_ENTRY (didefinisikan sebagai transaksi mandiri) yang akan menulis VARCHAR2 ke tabel lain. Transaksi otonom TIDAK mengganggu transaksi Anda saat ini (dari perspektif LOGICAL; waspadai dampak potensial terhadap kinerja) dan sehingga Anda dapat melihat apa yang terjadi melalui entri logging Anda terlepas dari KOMIT atau ROLLBACK dalam transaksi Anda saat ini. Yang mengatakan, Anda bisa melakukannya dengan satu pernyataan DML besar; Anda harus menggunakan loop.

Mempertimbangkan:

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;

Dengan diberikan di atas, Anda akan mendapatkan entri log untuk setiap 500 baris yang diproses terlepas dari keberhasilan tindakan panjang. Jika Anda membutuhkan duplikat data yang tepat untuk melihatnya saat berfungsi, saya sarankan membuat tabel duplikat dan memanggil prosedur yang akan menggandakan data (prosedur menjadi transaksi mandiri). Kemudian nuke data setelah-fakta. (Tidak perlu duplikasi.)

Lebih lanjut, jika ini untuk tujuan debugging, saya sarankan menghapus atau secara drastis mengurangi kebutuhan untuk penebangan seperti itu ketika hal-hal telah diuji. Dan, seperti biasa, uji, uji, uji pada sistem Anda sendiri untuk memverifikasi cara kerja. (Lihat komentar dari Niall untuk contoh yang baik tentang bagaimana logging dapat secara drastis mempengaruhi kinerja.)

(Akhirnya, karena saya lalai menyebutkannya sebelumnya: waspadalah dengan transaksi otonom. Pahami sepenuhnya sebelum mengimplementasikan, dan jangan menggunakannya "hanya karena". Mereka dapat digunakan dalam sejuta cara secara tidak benar (misalnya, misalnya, untuk ATTEMPT untuk hindari kesalahan mutasi pada pemicu), jadi selalu yang terbaik untuk menemukan alternatif, jika mungkin. Jika Anda tidak bisa, maka lanjutkan dengan hati-hati. Logging selama operasi yang lama selalu menjadi satu kasus di mana itu cukup aman (mengabaikan masalah kinerja), tetapi jangan Bergegas untuk menerapkannya ke penggunaan lain tanpa mengetahui konsekuensinya.)

5
Kerri Shotts

Tidak tersedia dalam 10g, tetapi DBMS_XA dapat memungkinkan transaksi untuk melewati beberapa sesi. Dengan menggunakan sesi kedua dapat melihat apa yang terjadi dalam transaksi

3
Gary

Selain informasi lain di sini, beberapa cara tambahan untuk mengirim informasi tentang transaksi yang tidak dikomit adalah mengirim email atau menulis ke file teks.

3
Leigh Riffel