ฉันสามารถเรียกใช้กระบวนงานที่เก็บไว้และส่งคืนได้ทันทีโดยไม่ต้องรอให้เสร็จหรือไม่


41

เรามีขั้นตอนการจัดเก็บที่ผู้ใช้สามารถเรียกใช้ด้วยตนเองเพื่อรับหมายเลขที่ปรับปรุงแล้วสำหรับรายงานที่ใช้อย่างต่อเนื่องตลอดทั้งวัน

ฉันมีขั้นตอนการจัดเก็บที่สองที่ควรเรียกใช้หลังจากการเรียกใช้กระบวนงานที่เก็บไว้ครั้งแรกเนื่องจากเป็นไปตามหมายเลขที่ได้รับจากขั้นตอนการจัดเก็บครั้งแรกนี้ แต่ใช้เวลานานกว่าในการเรียกใช้และเป็นกระบวนการแยกต่างหาก ทำให้ผู้ใช้รอในขณะที่โพรซีเดอร์ที่เก็บไว้นี้ที่ 2 รัน

มีวิธีให้โพรซีเดอร์ที่เก็บไว้หนึ่งโพรซีเดอร์เริ่มต้นโพรซีเดอร์ที่เก็บที่สองและส่งคืนทันทีโดยไม่รอผลลัพธ์หรือไม่?

ฉันใช้ SQL Server 2005


วิธีการจัดเก็บถูกเรียกว่าอย่างไร? โปรแกรมประยุกต์บนเว็บ ASP.NET? SSRS?
Mr.Brownstone


@ Mr.Brownstone มักจะถูกเรียกจากเว็บแอปพลิเคชัน ASP.Net ถึงแม้ว่ามันอาจถูกเรียกโดยมากกว่าหนึ่งในนั้น ฉันต้องตรวจสอบอีกครั้ง นอกจากนี้ยังได้รับการเรียกใช้ด้วยตนเองจาก SSRS เป็นครั้งคราว
ราเชล

@MartinSmith ฉันเคยทำงานกับนายหน้าบริการ SQL มาก่อนและหวังว่าจะมีวิธีที่ง่ายกว่านี้ ดูเหมือนว่าจะเป็นการตั้งค่าที่ซับซ้อนสำหรับบางสิ่งที่เรียบง่ายเช่นนี้
ราเชล

1
@MartinSmith นั่นเป็นสิ่งที่ฉันคิด - และสำหรับ SSRS ที่คุณทำไม่ได้ แต่สิ่งที่คุณทำได้คือการรวม Report Viewer ลงในแอปพลิเคชันและย้าย rdl ของคุณลงไป - ด้วยวิธีนี้จะทำให้สามารถเรียก async ได้ สำหรับรายงานเช่นกัน
Mr.Brownstone

คำตอบ:


27

ดูเหมือนว่ามีหลายวิธีในการทำสิ่งนี้ แต่ฉันพบวิธีที่ง่ายที่สุดคือMartin แนะนำให้ตั้งค่าโพรซีเดอร์ในงาน SQL และเริ่มต้นโดยใช้คำสั่งasynchronous sp_start_jobจากโพรซีเดอร์ที่เก็บไว้ของฉัน

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

ใช้งานได้กับฉันเท่านั้นเพราะฉันไม่จำเป็นต้องระบุพารามิเตอร์ใด ๆ สำหรับขั้นตอนการจัดเก็บของฉัน

ข้อเสนอแนะอื่น ๆ ที่อาจทำงานได้ขึ้นอยู่กับสถานการณ์ของคุณคือ

  • การใช้SQL Service Brokerเช่นMartinและSebastianแนะนำ นี่อาจเป็นคำแนะนำที่ดีที่สุดหากคุณไม่คำนึงถึงความซับซ้อนของการตั้งค่าและเรียนรู้วิธีการทำงาน
  • เล่นกระบวนการถ่ายทอดสดในรหัสที่รับผิดชอบในการดำเนินการจัดเก็บเช่นMr.Brownstone ปัญหา

    ไม่ใช่ความคิดที่ไม่ดี แต่ในกรณีของฉันขั้นตอนการจัดเก็บได้รับการเรียกจากหลายแห่งดังนั้นการค้นหาสถานที่เหล่านั้นทั้งหมด ขั้นตอนการจัดเก็บครั้งที่ 2 นั้นมีความสำคัญพอสมควรและการลืมดำเนินการอาจทำให้เกิดปัญหาที่สำคัญสำหรับ บริษัท ของเรา

  • ทำให้ขั้นตอนที่ 1 ตั้งธงและติดตั้งงานที่เกิดขึ้นในการตรวจสอบและธงที่ทำงานถ้าชุดเช่นJimbo ปัญหา ฉันไม่ใช่แฟนตัวยงของงานที่ต้องทำงานอย่างต่อเนื่องและตรวจสอบการเปลี่ยนแปลงทุกสองสามนาที แต่แน่นอนว่ามันเป็นตัวเลือกที่คุ้มค่าที่จะพิจารณาขึ้นอยู่กับสถานการณ์ของคุณ

3
ดูที่การดำเนินการตามขั้นตอนแบบอะซิงโครนัสสำหรับตัวอย่างที่พร้อมใช้งานโดยใช้ Service Broker ข้อดีเหนือกว่า sp_job ก็คือมันใช้งานได้กับ Express Edition และเป็น DB ทั้งหมดที่มีอยู่ (ไม่ต้องพึ่งพาตารางงาน MSDB) ต่อมามีความสำคัญมากในการล้มเหลวของ DBM และการกู้คืน HA / DR
Remus Rusanu

ยิงฉันเห็นมาร์ตินเชื่อมโยงบทความเดียวกัน ฉันจะแสดงความคิดเห็นสำหรับข้อบกพร่อง failover / DR
Remus Rusanu

@RemusRusanu: ก็เป็นหนึ่งในแหล่งข้อมูลที่ดีที่สุดเกี่ยวกับ Service Broker แต่ฉันคิดว่าคุณรู้แล้ว ;-)
แมเรียน

ฉันชอบลิงค์จาก @Rusanu แต่ฉันต้องการบางสิ่งที่ไม่มีการตอบสนอง (ซึ่งฉันคิดว่าตรงกับปัญหานี้) ฉันเขียนเวอร์ชันที่เรียบง่ายของฉันที่abamacus.blogspot.com/2016/05/…
Abacus

นอกจากนี้หากคุณพยายามเริ่มงานตัวแทนของ SQL งานนั้นจะล้มเหลวด้วยEXECUTE permission was denied on the object 'sp_start_job', database 'msdb', schema 'dbo'.ตัวแทนบริการหรือตัวแทน SQL ที่มีอยู่บน Azure ผมไม่ทราบว่าทำไม Microsoft EXECUTE ASYNC RematerializeExpensiveCacheTableหลังจากทศวรรษที่ผ่านมาและครึ่งหนึ่งของคนที่ขอปฏิเสธที่จะเพิ่ม
เอียนบอยด์

8

คุณสามารถใช้นายหน้าบริการพร้อมกับเปิดใช้งานคิว เมื่อคุณสามารถโพสต์พารามิเตอร์สำหรับการเรียกโพรซีเดอร์บนคิว ซึ่งใช้เวลานานกว่าการแทรก หลังจากทำธุรกรรมแล้วและอาจเกิดขึ้นอีกไม่กี่วินาทีการเปิดใช้งานจะเรียกขั้นตอนการรับสัญญาณแบบอะซิงโครนัสโดยอัตโนมัติ มันมากกว่า wuold ต้องใช้พารามิเตอร์ของคิวและทำงานที่ต้องการ


7

คำถามเก่านี้สมควรได้รับคำตอบที่ครอบคลุมมากขึ้น บางส่วนถูกกล่าวถึงในคำตอบ / ความคิดเห็นอื่น ๆ ที่นี่คนอื่น ๆ อาจหรืออาจไม่ทำงานในสถานการณ์ที่เฉพาะเจาะจงของ OP แต่อาจทำงานให้ผู้อื่นที่กำลังมองหาการโทร procs ที่เก็บไว้แบบอะซิงโครนัสจาก SQL

เพียงเพื่อจะชัดเจนทั้งหมด: TSQL ไม่ได้ (ด้วยตัวเอง) มีความสามารถที่จะเปิดตัวการดำเนินงานอื่น ๆ TSQL ถ่ายทอดสด

ไม่ได้หมายความว่าคุณยังมีตัวเลือกไม่มาก:

  • งานของ บริษัท ตัวแทน SQL : สร้างงาน SQL หลายและตารางการอย่างใดอย่างหนึ่งให้พวกเขาทำงานในเวลาที่ต้องการหรือเริ่มต้นพวกเขาถ่ายทอดสดจาก "ควบคุม" ที่เก็บไว้ proc sp_start_jobใช้ หากคุณจำเป็นต้องติดตามความคืบหน้าของพวกเขา programatically เพียงให้แน่ใจว่างานที่ปรับปรุงแต่ละตาราง JOB_PROGRESS ที่กำหนดเอง (หรือคุณสามารถตรวจสอบเพื่อดูว่าพวกเขาได้เสร็จสิ้นได้ใช้ฟังก์ชั่นที่ไม่มีเอกสารxp_sqlagent_enum_jobsตามที่อธิบายไว้ในบทความนี้ดีเกรกอรีเอเสน) คุณต้องสร้างงานที่แยกกันมากเท่าที่คุณต้องการให้กระบวนการแบบขนานทำงานแม้ว่าพวกเขาจะเรียกใช้ proc ที่เก็บไว้เดียวกันกับพารามิเตอร์ที่แตกต่างกัน
  • SSIS Package : สำหรับสถานการณ์แบบอะซิงโครนัสที่ซับซ้อนยิ่งขึ้นให้สร้างแพ็คเกจ SSIS ด้วยขั้นตอนการแยกสาขาอย่างง่าย SSIS จะเริ่มงานเหล่านั้นในแต่ละช่องซึ่ง SQL จะทำงานแบบขนาน เรียกแพคเกจ SSIS จากงานตัวแทนของ SQL
  • แอปพลิเคชันที่กำหนดเอง : เขียนแอปที่กำหนดเองอย่างง่ายในภาษาที่คุณเลือก (C #, Powershell, ฯลฯ ) โดยใช้วิธีการแบบอะซิงโครนัสจากภาษานั้น โทร proc ที่เก็บไว้ของ SQL ในแต่ละเธรดของแอปพลิเคชัน
  • OLE Automation : ใน SQL ใช้sp_oacreateและsp_oamethodเปิดกระบวนการใหม่เรียก proc ที่เก็บไว้ตามที่อธิบายไว้ในบทความนี้โดย Gregory A. Larsen
  • บริการนายหน้า : มองในการใช้บริการนายหน้าเป็นตัวอย่างที่ดีของการดำเนินการไม่ตรงกันในบทความนี้
  • การเรียกใช้ CLR Parallel : ใช้คำสั่ง CLR Parallel_AddSqlและParallel_Executeตามที่อธิบายไว้ในบทความนี้โดย Alan Kaplan (SQL2005 + เท่านั้น)
  • ภารกิจ Windows ที่กำหนดเวลาไว้ : แสดงเพื่อความสมบูรณ์ แต่ฉันไม่ใช่แฟนของตัวเลือกนี้

ถ้าเป็นฉันฉันอาจใช้ SQL Agent Agent หลายตัวในสถานการณ์ที่ง่ายกว่าและแพ็คเกจ SSIS ในสถานการณ์ที่ซับซ้อนมากขึ้น

ในกรณีของคุณการโทรงานตัวแทน SQL ดูเหมือนจะเป็นทางเลือกที่ง่ายและจัดการได้

หนึ่งความคิดเห็นสุดท้าย : SQL ได้พยายามที่จะขนานการดำเนินงานของแต่ละบุคคลเมื่อใดก็ตามที่มันสามารถ * ซึ่งหมายความว่าการทำงาน 2 งานในเวลาเดียวกันแทนที่จะเป็นงานกันไม่รับประกันว่างานจะเสร็จเร็วกว่า ทดสอบอย่างรอบคอบเพื่อดูว่ามันปรับปรุงอะไรจริง ๆ หรือไม่

เรามีนักพัฒนาที่สร้างแพ็คเกจ DTS เพื่อทำงาน 8 อย่างในเวลาเดียวกัน น่าเสียดายที่มันเป็นเพียงเซิร์ฟเวอร์ 4-CPU :)

* สมมติว่าการตั้งค่าเริ่มต้น สิ่งนี้สามารถแก้ไขได้โดยการเปลี่ยนแปลงระดับสูงสุดของความขนานหรือความสัมพันธ์ของมาสก์หรือโดยใช้คำแนะนำการค้นหา MAXDOP


6

ใช่วิธีหนึ่ง:

  1. เมื่อโพรซีเดอร์ที่เก็บครั้งแรกเสร็จสมบูรณ์แล้วจะแทรกเร็กคอร์ดพร้อมข้อมูลทั้งหมดที่จำเป็นสำหรับโพรซีเดอร์ที่เก็บที่สองเพื่อรัน
  2. กระบวนงานที่เก็บไว้ที่สองทำงานเป็นงานทุกนาทีหรือเวลาที่คุณตัดสินใจ
  3. มันจะตรวจสอบระเบียนที่แทรกทำกระบวนการและทำเครื่องหมายว่าบันทึกเสร็จสมบูรณ์

นี่เป็นการ จำกัด การดำเนินการของโพรซีเดอร์ที่เก็บไว้กับจำนวนของงานที่คุณรันซึ่งถ้าคุณต้องการให้เรียกไคลเอ็นต์นี้ทีละครั้งเป็นเรื่องปกติ - ในขณะที่คุณอาจมีลูกค้าจำนวนมากที่เรียกโพรซีเดอร์เดียวกันในเวลาเดียวกัน . นอกจากนี้ไคลเอ็นต์จะทราบได้อย่างไรว่างานเสร็จสมบูรณ์โดยไม่ต้องสำรวจฐานข้อมูลซ้ำ ๆ เพื่อดูว่ามีการตั้งค่าสถานะหรือไม่
Mr.Brownstone

1
@ Mr.Brownstone - อาจเป็นไปได้ว่างานสามารถประมวลผลงานค้างได้มากกว่าหนึ่งงานโดยการเรียกโพรซีเดอร์ที่เก็บไว้ต่างกันเมื่อรัน โพรซีเดอร์ที่เก็บไว้อาจเรียกsp_start_jobเพื่อเริ่มต้นหรือสร้างงานตามที่ต้องการแบบไดนามิกเพื่อหลีกเลี่ยงการโพลทุกนาที แต่ความซับซ้อนสำหรับกรณีนั้นอาจหมายความว่ามันจะไม่ง่ายกว่านายหน้าบริการ
Martin Smith

@MartinSmith ฉันมีการตั้งค่างานสำหรับขั้นตอนการจัดเก็บครั้งที่ 2 นี้อยู่แล้วเพราะมันเคยถูกเรียกใช้ทุกคืนจนกว่าเราจะพบปัญหาบางอย่างที่ไม่ได้ซิงค์อย่างถูกต้องกับหมายเลขของขั้นตอนที่ 1 ถ้าฉันเริ่มงานจากโพรซีเดอร์ที่เก็บไว้ครั้งที่ 1 มันจะรันแบบอะซิงโครนัสและกลับจาก SP ทันทีหรือไม่
ราเชล

@Rachel - ใช่ sp_start_jobส่งคืนทันที จำไม่ได้ว่าต้องการสิทธิ์อะไร
Martin Smith

1
การเริ่มงานจากขั้นตอน / ฐานข้อมูลอื่นเป็นปัญหาที่ค่อนข้างซับซ้อนหากคุณไม่ต้องการเปิดช่องโหว่ความปลอดภัยขนาดใหญ่ Erland Sommarskog มีบทความเกี่ยวกับเทคนิคต่าง ๆ ที่คุณต้องรวม: sommarskog.se/grantperm.html อย่างไรก็ตามไม่มีวิธีแก้ปัญหาที่สมบูรณ์ในนั้น
เซบาสเตียนมีน

1

ความเป็นไปได้อีกอย่างหนึ่งก็คือการได้รับโพรซีเดอร์ที่เก็บไว้ครั้งที่ 1 เพื่อเขียนไปยังตารางการตรวจสอบเมื่อมันเสร็จสมบูรณ์และวางทริกเกอร์บนตารางการตรวจสอบที่เรียกใช้โพรซีเดอร์ที่เก็บไว้ลำดับที่ 2 เมื่อเขียนตารางการตรวจสอบ ไม่จำเป็นต้องทำการสำรวจความคิดเห็นอย่างต่อเนื่องและไม่จำเป็นต้องมีงานตัวแทนของเซิร์ฟเวอร์ SQL เพิ่มเติม


3
กระบวนงานที่เก็บไว้ครั้งแรกจะไม่ส่งคืนจนกว่าการแทรกไปยังตารางการตรวจสอบจะเสร็จสมบูรณ์และจะไม่เกิดขึ้นจนกว่าทริกเกอร์จะดำเนินการเสร็จสิ้น (รวมถึงการเรียกไปยังกระบวนงานที่เก็บไว้ที่ 2)
Martin Smith

1
ฉันดูแล้วโดยใช้ Trigger แต่ทริกเกอร์จะทำงานพร้อมกันกับคำสั่งINSERTหรือUPDATEไม่แบบอะซิงโครนัสดังนั้นมาร์ตินถูกต้องว่าขั้นตอนที่ 1 จะยังคงรอจนกว่าขั้นตอนที่ 2 จะกลับมาเสร็จสิ้น
ราเชล
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.