Dapatkah saya meluncurkan prosedur tersimpan dan segera kembali tanpa menunggu sampai selesai?

41

Kami memiliki prosedur tersimpan yang dapat dijalankan pengguna secara manual untuk mendapatkan nomor yang diperbarui untuk laporan yang digunakan terus-menerus sepanjang hari.

Saya memiliki prosedur tersimpan kedua yang harus dijalankan setelah prosedur tersimpan pertama dijalankan karena didasarkan pada angka yang diperoleh dari prosedur tersimpan pertama ini, namun itu membutuhkan waktu lebih lama untuk dijalankan dan untuk proses yang terpisah, jadi saya tidak ingin membuat pengguna menunggu saat prosedur tersimpan ke-2 ini dijalankan.

Apakah ada cara agar satu prosedur tersimpan memulai prosedur tersimpan kedua, dan segera kembali tanpa menunggu hasil?

Saya menggunakan SQL Server 2005.

Rachel
sumber
Bagaimana prosedur tersimpan dipanggil? Aplikasi web ASP.NET? SSR?
Mr.Brownstone
@ Mr.Brownstone Biasanya dipanggil dari aplikasi web ASP.Net, meskipun mungkin dipanggil oleh lebih dari satu. Saya harus memeriksa ulang. Itu juga kadang-kadang dijalankan secara manual dari SSRS.
Rachel
@ MartinSmith Saya pernah bekerja dengan broker layanan SQL di masa lalu, dan berharap ada cara yang lebih sederhana. Sepertinya pengaturan yang rumit untuk hal sesederhana ini.
Rachel
1
@MartinSmith cukup banyak yang saya pikirkan - juga, untuk SSR tidak ada yang tidak bisa Anda lakukan selain menggabungkan Report Viewer ke dalam aplikasi dan memindahkan rdl ke dalamnya - dengan cara itu dimungkinkan untuk melakukan panggilan async untuk laporan juga.
Mr.Brownstone

Jawaban:

27

Sepertinya ada beberapa cara untuk melakukan ini, tetapi saya menemukan cara paling sederhana adalah saran Martin untuk mengatur prosedur dalam pekerjaan SQL, dan memulainya menggunakan perintah sp_start_job asynchronous dari prosedur tersimpan saya.

EXEC msdb.dbo.sp_start_job @job_name='Run2ndStoredProcedure'

Ini hanya berfungsi untuk saya karena saya tidak perlu menentukan parameter apa pun untuk prosedur tersimpan saya.

Saran lain yang dapat bekerja tergantung pada situasi Anda

  • Menggunakan SQL Service Broker seperti yang disarankan Martin dan Sebastian . Ini mungkin saran terbaik jika Anda tidak keberatan dengan kerumitan pengaturannya dan mempelajari cara kerjanya.
  • Menjalankan proses secara asinkron dalam kode yang bertanggung jawab untuk menjalankan prosedur tersimpan, seperti yang disarankan Mr.Brownstone .

    Bukan ide yang buruk, namun dalam kasus saya prosedur tersimpan dipanggil dari beberapa tempat, jadi menemukan semua tempat itu dan memastikan mereka memanggil prosedur ke-2 juga tampaknya tidak praktis. Juga, prosedur 2 yang disimpan cukup kritis, dan lupa menjalankannya dapat menyebabkan beberapa masalah besar bagi perusahaan kami.

  • Buat prosedur pertama menetapkan bendera, dan atur pekerjaan berulang untuk memeriksa bendera itu dan jalankan jika ditetapkan, seperti yang disarankan Jimbo . Saya bukan penggemar berat pekerjaan yang berjalan terus-menerus dan memeriksa perubahan setiap beberapa menit, tetapi itu jelas merupakan opsi yang layak dipertimbangkan tergantung pada situasi Anda.
Rachel
sumber
3
Lihat Eksekusi Prosedur Asinkron untuk contoh yang siap digunakan menggunakan Pialang Layanan. Keuntungan daripada sp_job adalah ia berfungsi pada Edisi Express dan sepenuhnya berisi DB (tidak ada ketergantungan pada tabel pekerjaan MSDB). Nanti sangat penting dalam kegagalan DBM dan pemulihan HA / DR.
Remus Rusanu
Tembak, saya melihat Martin menautkan artikel yang sama. Saya akan meninggalkan komentar untuk argumen failover / DR.
Remus Rusanu
@RemusRusanu: yah, itu salah satu sumber informasi terbaik tentang Service Broker, tapi saya kira Anda sudah tahu ;-).
Marian
Saya menyukai tautan dari @Rusanu, tetapi saya menginginkan sesuatu tanpa respons (yang menurut saya cocok dengan masalah ini). Saya menulis versi sederhana saya di abamacus.blogspot.com/2016/05/...
Abacus
Juga jika Anda mencoba untuk memulai pekerjaan Agen SQL, itu akan gagal dengan EXECUTE permission was denied on the object 'sp_start_job', database 'msdb', schema 'dbo'.Pialang Layanan juga, atau Agen Sql, ada di Azure. Saya tidak tahu mengapa Microsoft, setelah satu setengah dekade orang bertanya, menolak untuk menambahkan EXECUTE ASYNC RematerializeExpensiveCacheTable.
Ian Boyd
8

Anda dapat menggunakan broker layanan bersama dengan aktivasi di antrian. Dengan itu Anda dapat memposting parameter untuk panggilan prosedur pada antrian. Itu membutuhkan waktu sebanyak sisipan. Setelah transaksi dilakukan dan berpotensi beberapa detik lagi, aktivasi akan secara otomatis memanggil prosedur penerima secara tidak sinkron. Daripada hanya harus mengambil parameter antrian dan melakukan pekerjaan yang diinginkan.

Sebastian Meine
sumber
7

Pertanyaan lama ini layak mendapat jawaban yang lebih komprehensif. Beberapa di antaranya disebutkan dalam jawaban / komentar lain di sini, yang lain mungkin atau mungkin tidak bekerja untuk situasi spesifik OP, tetapi mungkin bekerja untuk orang lain yang mencari memanggil procs yang disimpan secara asinkron dari SQL.

Secara eksplisit: TSQL tidak (dengan sendirinya) memiliki kemampuan untuk meluncurkan operasi TSQL lainnya secara tidak sinkron .

Itu tidak berarti Anda masih tidak memiliki banyak opsi:

  • Pekerjaan SQL Agent : Buat beberapa pekerjaan SQL, dan jadwalkan untuk dijalankan pada waktu yang diinginkan, atau mulai secara asinkron dari "master control" yang disimpan menggunakan proc sp_start_job. Jika Anda perlu memantau progresnya secara programatis, pastikan masing-masing pekerjaan memperbarui tabel JOB_PROGRESS khusus (atau Anda dapat memeriksa apakah mereka telah selesai menggunakan fungsi tidak berdokumen xp_sqlagent_enum_jobsseperti dijelaskan dalam artikel yang sangat bagus ini oleh Gregory A. Larsen). Anda harus membuat pekerjaan terpisah sebanyak yang Anda inginkan untuk menjalankan proses paralel, bahkan jika mereka menjalankan proc tersimpan yang sama dengan parameter yang berbeda.
  • Paket SSIS : Untuk skenario asinkron yang lebih rumit, buat paket SSIS dengan alur tugas percabangan sederhana. SSIS akan meluncurkan tugas-tugas tersebut dalam masing-masing spid, yang akan dieksekusi SQL secara paralel. Panggil paket SSIS dari pekerjaan agen SQL.
  • Aplikasi khusus : Tulis aplikasi kustom sederhana dalam bahasa pilihan Anda (C #, Powershell, dll), menggunakan metode asinkron yang disediakan oleh bahasa itu. Panggil proc tersimpan SQL di setiap utas aplikasi.
  • OLE Automation : Dalam SQL, gunakan sp_oacreatedan sp_oamethoduntuk meluncurkan proses baru memanggil masing-masing proc tersimpan lainnya seperti yang dijelaskan dalam artikel ini , juga oleh Gregory A. Larsen.
  • Pialang Layanan : Lihat ke dalam menggunakan Pialang Layanan , contoh yang baik dari eksekusi asinkron dalam artikel ini .
  • Eksekusi Paralel CLR : Gunakan perintah CLR Parallel_AddSqldan Parallel_Executeseperti yang dijelaskan dalam artikel ini oleh Alan Kaplan (SQL2005 + saja).
  • Tugas Windows Terjadwal : Terdaftar untuk kelengkapan, tapi saya bukan penggemar opsi ini.

Jika itu saya, saya mungkin akan menggunakan beberapa SQL Agent Jobs dalam skenario yang lebih sederhana, dan paket SSIS dalam skenario yang lebih kompleks.

Dalam kasus Anda, memanggil pekerjaan SQL Agent terdengar seperti pilihan yang sederhana dan mudah dikelola.

Satu komentar terakhir : SQL sudah mencoba untuk memparalelkan operasi individual kapan saja *. Ini berarti menjalankan 2 tugas pada saat yang sama alih-alih setelah satu sama lain bukan jaminan bahwa itu akan selesai lebih cepat. Uji dengan cermat untuk melihat apakah itu benar-benar meningkatkan sesuatu atau tidak.

Kami memiliki pengembang yang membuat paket DTS untuk menjalankan 8 tugas secara bersamaan. Sayangnya, itu hanya server 4-CPU :)

* Dengan asumsi pengaturan default. Ini dapat dimodifikasi dengan mengubah Derajat Maksimal Paralelisme atau Topeng Affinity server, atau dengan menggunakan petunjuk permintaan MAXDOP.

BradC
sumber
6

Ya, satu metode:

  1. Ketika prosedur tersimpan 1 selesai, ia menyisipkan catatan dengan semua informasi yang diperlukan agar prosedur tersimpan kedua dijalankan
  2. Prosedur tersimpan kedua berjalan sebagai pekerjaan, setiap menit atau berapa kali Anda memutuskan
  3. Ia memeriksa catatan yang dimasukkan, melakukan prosesnya dan menandai catatan sebagai lengkap
Jimbo
sumber
Ini membatasi pelaksanaan prosedur tersimpan pada jumlah pekerjaan yang Anda jalankan yang jika Anda hanya ingin ini dipanggil oleh satu klien pada suatu waktu baik-baik saja - sedangkan Anda mungkin memiliki beberapa klien yang memanggil prosedur yang sama pada waktu yang sama . Juga, bagaimana klien tahu pekerjaan telah selesai tanpa berulang kali polling database untuk mengetahui apakah suatu bendera telah ditetapkan?
Mr.Brownstone
1
@ Mr.Brownstone - Berpotensi pekerjaan dapat memproses lebih dari satu tugas luar biasa yang di-antri oleh panggilan prosedur tersimpan yang berbeda saat dijalankan. Prosedur tersimpan juga dapat meminta sp_start_jobuntuk memulainya atau menciptakan pekerjaan yang diperlukan secara dinamis untuk menghindari polling setiap menit, tetapi kompleksitas untuk kasus itu mungkin berarti itu tidak akan lebih sederhana daripada broker layanan.
Martin Smith
@ MartinSmith Saya sebenarnya sudah memiliki pengaturan pekerjaan untuk prosedur tersimpan ke-2 ini karena dulu dijalankan setiap malam sampai kami menemukan beberapa masalah dengan itu tidak disinkronkan dengan benar dengan nomor prosedur 1. Jika saya memulai pekerjaan dari prosedur tersimpan 1, apakah ini akan berjalan secara tidak sinkron dan segera kembali dari SP?
Rachel
@Rachel - Ya. sp_start_jobsegera kembali. Tidak dapat mengingat izin apa yang dibutuhkan.
Martin Smith
1
Memulai pekerjaan dari prosedur / database lain adalah masalah yang cukup rumit jika Anda tidak ingin membuka celah keamanan yang besar. Erland Sommarskog memiliki artikel tentang berbagai teknik yang perlu Anda gabungkan: sommarskog.se/grantperm.html Namun, tidak ada solusi lengkap di sana.
Sebastian Meine
1

Kemungkinan lain adalah membuat prosedur tersimpan ke-1 untuk menulis ke meja audit ketika selesai dan menempatkan pemicu di atas meja audit yang meluncurkan prosedur tersimpan ke-2 saat tabel audit ditulis. Tidak perlu terus-menerus melakukan jajak pendapat dan tidak perlu pekerjaan agen SQL Server tambahan.

paco
sumber
3
Prosedur tersimpan pertama tidak akan kembali sampai penyisipan ke tabel audit selesai dan itu tidak akan terjadi sampai pelatuk selesai dieksekusi (termasuk panggilan ke prosedur tersimpan 2)
Martin Smith
1
Saya sudah melihat ke dalam menggunakan Trigger, tetapi pemicu dijalankan secara sinkron dengan pernyataan INSERTatau UPDATE, tidak asinkron, sehingga Martin benar bahwa prosedur 1 masih akan berakhir menunggu sampai prosedur 2 selesai kembali.
Rachel