2013-04-10 71 views
9

Tôi là nhà phát triển trên ứng dụng web sử dụng cơ sở dữ liệu Oracle. Tuy nhiên, thường thì giao diện người dùng sẽ kích hoạt các hoạt động của cơ sở dữ liệu mất một thời gian để xử lý. Kết quả là, khách hàng muốn có một thanh tiến trình khi các tình huống này xảy ra.Xác định tiến trình của truy vấn (Oracle PL/SQL)

Gần đây tôi đã phát hiện ra rằng tôi có thể truy vấn V $ SESSION_LONGOPS từ kết nối thứ hai và điều này thật tuyệt, nhưng nó chỉ hoạt động trên các hoạt động mất hơn 6 giây. Điều này có nghĩa là tôi không thể cập nhật thanh tiến trình trong giao diện người dùng cho đến khi 6 giây trôi qua.

Tôi đã nghiên cứu về thời gian chờ đợi trong V $ SESSION nhưng theo như tôi thấy, điều đó không bao gồm việc chờ truy vấn.

Có cách nào để có được tiến trình truy vấn hiện đang chạy của một phiên không? Hay tôi chỉ nên ẩn thanh tiến trình cho đến khi 6 giây trôi qua?

+3

Nếu bạn có hoạt động 100 x 1 giây. Không ai trong số họ sẽ xuất hiện trong SESSION_LONGOPS. Nếu bạn có 2 hoạt động liên tiếp mười giây, sau khi hoạt động đầu tiên của bạn đạt 100%, hoạt động thứ hai sẽ bắt đầu ở mức 0%. Đó sẽ là một thanh tiến trình bực bội.Tôi nghĩ đây là một trong những thứ cần vòng tròn xoay vòng, không phải thanh trạng thái, bởi vì bạn không biết phải mất bao lâu. –

Trả lời

1

Tôi đã thực hiện khá nhiều phát triển web với Oracle qua nhiều năm và thấy rằng hầu hết người dùng thích thanh tiến trình không xác định, hơn thanh xác định không chính xác (một thanh khá nhiều bất kỳ thanh tiến trình nào gây phiền toái cho tôi Microsoft's không có kết thúc), và tiếc là không có cách nào sai lầm để xác định chính xác tiến trình truy vấn. Trong khi nghiên cứu của bạn về khả năng mở rộng dài là đáng ngưỡng mộ và chắc chắn sẽ giúp tiến trình truy vấn cơ sở dữ liệu đáng tin cậy hơn, nó không thể tính đến vô số các biến khác có thể/sẽ ảnh hưởng đến giao dịch của hoạt động web tiến độ (tải mạng, tải cơ sở dữ liệu, tải máy chủ ứng dụng, phân tích dữ liệu phía máy khách, người dùng nhấp vào nút gửi 1.000 lần, v.v ...).

Tôi muốn gắn với phương pháp tiến trình không xác định bằng cách sử dụng gọi lại Javascript. Triển khai dễ dàng hơn nhiều và nó sẽ quản lý kỳ vọng của người dùng của bạn khi thích hợp.

8

Các hoạt động này có phải là các cuộc gọi Pl/SQL hay chỉ là SQL dài hạn?

Với các hoạt động PL/SQL, chúng tôi có thể soạn tin nhắn với SET_SESSION_LONGOPS() trong gói DBMS_APPLICATION_INFO. Chúng tôi có thể theo dõi các tin nhắn này trong V$SESSION_LONGOPS. Find out more.

Để làm việc này, bạn cần có khả năng định lượng hoạt động theo đơn vị công việc. Đây phải là sự lặp lại của một cái gì đó cụ thể, và số không phải thời gian. Vì vậy, nếu hoạt động được chèn 10.000 hàng bạn có thể chia thành 10 lô. Tham số totalwork là số lô (ví dụ: 10) và bạn gọi SET_SESSION_LONGOPS() sau mỗi 1000 hàng để tăng tham số sofar. Điều này sẽ cho phép bạn để làm cho một nhiệt kế mười khối.

Các thư này dựa trên phiên nhưng không có cách tự động phân biệt thư hiện tại từ thư trước đó từ cùng một phiên & SID. Tuy nhiên, nếu bạn gán UID cho tham số context thì bạn có thể sử dụng giá trị đó để lọc chế độ xem.


Điều này sẽ không hoạt động cho một truy vấn chạy dài, bởi vì không có cách nào để chia chúng thành nhiều phần.

+0

Cảm ơn tất cả các câu trả lời của bạn. Tôi sẽ gắn bó với một thanh tiến trình quay cho hầu hết các hoạt động, nhưng đối với các truy vấn rất dài (các truy vấn mất vài phút), tôi đang nghĩ đến việc ghi lại thời gian truy vấn cuối cùng chạy và sử dụng để ước tính thanh tiến trình. Ngay cả khi nó hơi tắt, khi bạn chờ vài phút để thực hiện một hành động, thanh tiến trình ít nhất cũng cho người dùng hy vọng rằng có điều gì đó đang xảy ra hơn là bị mù. –

2

tôi thấy điều này rất hữu ích

dbms_session.set_module("MY Program" , "Kicking off ... ") 
.. 
dbms_session.set_action("Extracting data ... ") 
.. 
dbms_session.set_action("Transforming data ... ") 
.. 

bạn có thể theo dõi quá trình sử dụng

select module , action from v$session where sid = :yoursessionid 
0

Sử dụng V $ _SESSION_LONGOPS đòi hỏi phải thiết lập TIMED_STATISTICS = true hoặc SQL_TRACE = true. Lược đồ cơ sở dữ liệu của bạn phải được cấp đặc quyền hệ thống ALTER SESSION để làm như vậy.

Tôi đã từng thử sử dụng V $ _SESSION_LONGOPS với truy vấn phức tạp và chạy dài. Nhưng nó bật lên rằng V $ _SESSION_LONGOPS có thể hiển thị tiến trình của các phần của truy vấn như quét toàn bộ bảng, tham gia hoạt động và tương tự.

Xem thêm: http://www.dba-oracle.com/t_v_dollar_session_longops.htm

gì bạn có thể làm chỉ là để hiển thị cho người sử dụng "truy vấn vẫn chạy". Tôi đã triển khai một số <DIV> được lồng vào một <TD> lâu hơn với mọi yêu cầu trạng thái được gửi bởi trình duyệt. Yêu cầu trạng thái được bắt đầu bằng window.SetTimeout (cứ 3 giây một lần) và là các cuộc gọi AJAX đến quy trình phía máy chủ. Báo cáo trạng thái được trả về bởi quy trình phía máy chủ chỉ cần nói "chúng tôi vẫn đang chạy". Chiều rộng của thanh tiến trình (tức là chiều rộng của <DIV>) tăng 5% chiều rộng <TD> mỗi lần và được đặt lại thành 5% sau khi hiển thị 100%.

Đối với các truy vấn chạy dài, bạn có thể theo dõi thời gian họ đã thực hiện trong một bảng riêng biệt, có thể với các mục nhập riêng lẻ để thay đổi điều khoản. Bạn có thể sử dụng điều này để hiển thị thời gian trung bình cộng với thời gian vừa trôi qua trong hộp thoại phía máy khách.

Nếu bạn có một thủ tục SQL dài chạy PL/hoặc những thứ tương tự ở phía máy chủ làm vài bước, hãy thử này:

  • tạo một bảng cho thông điệp tình trạng
  • sử dụng một chìa khóa duy nhất cho bất kỳ quá trình người dùng bắt đầu. Đề xuất: ngày javascript của khách hàng trong mili giây + ID phiên.
  • trong trường hợp quy trình chạy dài được bắt đầu bằng liên kết trong cửa sổ trình duyệt, tạo công việc bằng DBMS_JOB.SUBMIT để chạy quy trình thay vì chạy thủ tục trực tiếp
  • viết một quy trình ngắn cập nhật bảng trạng thái , sử dụng PRAGMA AUTONOMOUS_TRANSACTION. Pragma này cho phép bạn thực hiện các cập nhật cho bảng trạng thái mà không cần phải cập nhật các thủ tục chính của bạn. Mỗi bước chính trong quy trình chính của bạn phải có mục nhập riêng trong bảng trạng thái này.
  • viết một thủ tục để truy vấn bảng trạng thái được gọi là bởi trình duyệt
  • viết một thủ tục được gọi bằng một cuộc gọi AJAX nếu việc sử dụng nhấp chuột "Hủy" hoặc đóng cửa sổ
  • viết một thủ tục đó được gọi là theo thủ tục chính sau khi hoàn thành mỗi bước: nó truy vấn bảng trạng thái và đặt ra một ngoại lệ với một số trong 20.000 nếu cờ hủy được đặt hoặc trình duyệt không truy vấn trạng thái trong 60 giây. Trong trình xử lý ngoại lệ của thủ tục chính, hãy tìm kiếm lỗi này, thực hiện khôi phục và cập nhật bảng trạng thái.