저장 프로 시저를 시작하고 완료 될 때까지 기다리지 않고 즉시 반환 할 수 있습니까?


41

우리는 사용자가 수동으로 실행하여 하루 종일 지속적으로 사용되는 보고서의 일부 업데이트 된 번호를 얻을 수있는 저장 프로 시저가 있습니다.

이 첫 번째 저장 프로 시저에서 얻은 숫자를 기반으로하기 때문에 첫 번째 저장 프로 시저 실행 후에 실행 해야하는 두 번째 저장 프로 시저가 있지만 실행하는 데 시간이 오래 걸리고 별도의 프로세스를 수행하기 때문에 원하지 않습니다. 이 두 번째 저장 프로 시저가 실행되는 동안 사용자를 기다리십시오.

하나의 저장 프로 시저가 두 번째 저장 프로 시저를 시작하고 결과를 기다리지 않고 즉시 반환하는 방법이 있습니까?

SQL Server 2005를 사용하고 있습니다.


저장 프로시 저는 어떻게 호출됩니까? ASP.NET 웹 애플리케이션? SSRS?
Mr.Brownstone


@ Mr.Brownstone 일반적으로 ASP.Net 웹 응용 프로그램에서 호출되지만 둘 이상에서 호출 될 수도 있습니다. 다시 확인해야합니다. 또한 때때로 SSRS에서 수동으로 실행됩니다.
Rachel

@MartinSmith 나는 과거 SQL 서비스 브로커와 함께 한 번 일했으며 더 간단한 방법이 있기를 바랐습니다. 이처럼 간단한 것에 대한 복잡한 설정처럼 보입니다.
Rachel

1
@MartinSmith-SSRS의 경우 할 수 없지만 할 수있는 일은 보고서 뷰어를 응용 프로그램에 통합하고 rdl을 이동시키는 것입니다. 그러면 비동기식 호출이 가능합니다. 보고서도 마찬가지입니다.
Mr.Brownstone

답변:


27

여러 가지 방법으로이 작업을 수행하는 것처럼 보이지만 가장 간단한 방법은 Martin 이 SQL 작업에서 프로 시저를 설정하고 내 저장 프로 시저에서 비동기 sp_start_job 명령을 사용하여 시작하는 제안 이라는 것을 알았 습니다 .

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

저장 프로 시저에 매개 변수를 지정할 필요가 없기 때문에 이것은 나에게만 효과적입니다.

상황에 따라 작동 할 수있는 다른 제안은 다음과 같습니다.

  • MartinSebastian 과 같은 SQL Service Broker를 사용하는 것이 좋습니다. 복잡하게 설정하고 작동 방식을 배우는 것이 마음에 들지 않는다면 이것은 아마도 가장 좋은 제안 일 것입니다.
  • Mr.Brownstone이 제안한 것처럼 저장 프로 시저를 실행하는 코드에서 프로세스를 비동기식으로 실행합니다 .

    그러나 나쁜 생각은 아니지만 제 경우에는 저장 프로 시저가 여러 곳에서 호출되므로 모든 장소를 찾아서 두 번째 절차를 호출하는 것도 그렇게 실용적이지 않은 것 같습니다. 또한 두 번째 저장 프로시 저는 매우 중요하므로 실행을 잊어 버리면 회사에 큰 문제가 발생할 수 있습니다.

  • 첫 번째 프로 시저에 플래그를 설정하고 반복 작업을 설정하여 해당 플래그를 확인하고 Jimbo가 제안한대로 해당 플래그가 설정되어 있는지 실행하십시오 . 나는 끊임없이 실행되고 몇 분마다 변경 사항을 확인하는 일을 좋아하지 않지만 상황에 따라 고려해야 할 옵션입니다.

3
Service Broker를 사용하는 즉시 사용 가능한 예제 는 비동기 프로 시저 실행 을 살펴보십시오 . sp_job의 장점은 Express Edition에서 작동하며 완전히 DB에 포함되어 있다는 것입니다 (MSDB 작업 테이블에 대한 종속성 없음). 나중에 DBM 장애 조치 및 HA / DR 복구에서 매우 중요합니다.
레무스

쏴, 나는 마틴이 같은 기사를 연결 한 것을 본다. 장애 조치 / DR 인수에 대한 의견을 남길 것입니다.
레무스 루사 누

@RemusRusanu : 글쎄, 그건 Service Broker에 관한 최고의 정보 소스 중 하나이지만, 당신은 이미 알고 있다고 가정합니다 ;-).
Marian

@Rusanu의 링크가 마음에 들었지만 응답이없는 것을 원했습니다 (이 문제와 일치한다고 생각합니다). abamacus.blogspot.com/2016/05/…
Abacus

또한 SQL 에이전트 작업을 시작하려고하면 EXECUTE permission was denied on the object 'sp_start_job', database 'msdb', schema 'dbo'.Azure에 Service Broker 또는 Sql Agent도 존재하지 않으므로 실패 합니다. 10 년 반이 지난 후에 Microsoft가 왜 추가를 거부하는지 모르겠습니다 EXECUTE ASYNC RematerializeExpensiveCacheTable.
Ian Boyd

8

서비스 브로커를 큐에서 활성화와 함께 사용할 수 있습니다. 이를 통해 프로 시저 호출에 대한 매개 변수를 큐에 게시 할 수 있습니다. 인서트만큼 많은 시간이 걸립니다. 트랜잭션이 커밋되고 몇 초 후에 잠재적으로 활성화되면 수신자 프로 시저가 비동기 적으로 자동으로 호출됩니다. 그냥 wuold보다 대기열의 매개 변수를 가져 와서 원하는 작업을 수행해야합니다.


7

이 오래된 질문은 더 포괄적 인 답변이 필요합니다. 이 중 일부는 여기에 다른 답변 / 설명에 언급되어 있고 다른 일부는 OP의 특정 상황에서 작동하거나 작동하지 않을 수 있지만 SQL에서 저장된 프로세스를 비동기식으로 호출하려는 다른 사람에게는 작동 할 수 있습니다.

완전히 명시 적으로 말하면 : TSQL 자체 는 다른 TSQL 작업을 비동기 적으로 시작할 수있는 기능 없습니다 .

그렇다고 아직 많은 옵션이 없다는 것을 의미하지는 않습니다.

  • SQL 에이전트 작업 : 여러 SQL 작업을 작성하고 원하는 시간에 실행되도록 스케줄하거나을 사용하여 "마스터 제어"저장 프로 시저에서 비동기식으로 시작하십시오 sp_start_job. 프로그래밍 방식으로 진행 상황을 모니터링해야하는 경우 작업이 각각 사용자 정의 JOB_PROGRESS 테이블을 업데이트하는지 확인하십시오 (또는 Gregory A. Larsen 의이 우수한 기사xp_sqlagent_enum_jobs설명 된대로 문서화되지 않은 기능 을 사용하여 완료했는지 확인할 수 있습니다 ). 서로 다른 매개 변수로 동일한 스토어드 프로 시저를 실행하더라도 병렬 프로세스를 실행하려는만큼 별도의 작업을 작성해야합니다.
  • SSIS 패키지 :보다 복잡한 비동기 시나리오의 경우 간단한 분기 작업 흐름으로 SSIS 패키지를 만듭니다. SSIS는 이러한 작업을 개별 spid로 시작하여 SQL이 병렬로 실행합니다. SQL 에이전트 작업에서 SSIS 패키지를 호출하십시오.
  • 사용자 지정 응용 프로그램 : 해당 언어에서 제공하는 비동기 메서드를 사용하여 원하는 언어 (C #, Powershell 등)로 간단한 사용자 지정 응용 프로그램을 작성합니다. 각 애플리케이션 스레드에서 SQL 저장 프로 시저를 호출하십시오.
  • OLE 자동화 : SQL 에서이 기사에 설명 된대로 Gregory A. Larsen에 의해 서로 저장된 proc을 호출하는 새 프로세스를 사용 sp_oacreate하고 sp_oamethod실행 하십시오 .
  • Service Broker : 이 기사의 비동기 실행에 대한 좋은 예인 Service Broker를 살펴보십시오 .
  • CLR 병렬 실행 : 사용 CLR 명령 Parallel_AddSqlParallel_Execute에 설명 된대로 이 문서 앨런 카플란에 의해 (SQL2005 + 만 해당).
  • 예약 된 Windows 작업 : 완전성에 대해 나열되었지만이 옵션에 관심이 없습니다.

만약 그렇다면 간단한 시나리오에서는 여러 개의 SQL 에이전트 작업을 사용하고보다 복잡한 시나리오에서는 SSIS 패키지를 사용했을 것입니다.

귀하의 경우 SQL 에이전트 작업을 호출하는 것은 간단하고 관리하기 쉬운 선택처럼 들립니다.

마지막 의견 : SQL은 가능할 때마다 개별 작업을 병렬화하려고 이미 시도합니다. 즉, 서로를 대신하지 않고 동시에 2 개의 작업을 실행한다고해서 더 빨리 완료 될 것이라는 보장은 없습니다. 실제로 어떤 것이 개선되는지 아닌지 신중하게 테스트하십시오.

동시에 8 개의 작업을 실행하기 위해 DTS 패키지를 만든 개발자가있었습니다. 불행히도, 그것은 단지 4 CPU 서버였습니다 :)

* 기본 설정을 가정합니다. 서버의 최대 병렬 처리 수준 또는 선호도 마스크를 변경하거나 MAXDOP 쿼리 힌트를 사용하여이를 수정할 수 있습니다.


6

예, 한 가지 방법 :

  1. 첫 번째 저장 프로 시저가 완료되면 두 번째 저장 프로 시저를 실행하는 데 필요한 모든 정보가 포함 된 레코드가 삽입됩니다.
  2. 두 번째 저장 프로시 저는 매분 또는 결정 시간마다 작업으로 실행됩니다.
  3. 삽입 된 레코드를 확인하고 처리하며 레코드를 완료된 것으로 표시합니다.

이렇게하면 저장 프로 시저의 실행이 실행중인 작업 수로 제한됩니다. 한 번에 한 클라이언트에서만이 작업을 호출하려는 경우에는 괜찮지 만 동시에 여러 클라이언트가 동일한 프로 시저를 호출 할 수 있습니다 . 또한 클라이언트는 플래그가 설정되었는지 확인하기 위해 데이터베이스를 반복적으로 폴링하지 않고 작업이 완료되었음을 어떻게 알 수 있습니까?
Mr.Brownstone

1
@ Mr.Brownstone-잠재적으로 작업이 실행될 때 다른 저장 프로 시저 호출에 의해 대기중인 둘 이상의 미해결 작업을 처리 할 수 ​​있습니다. 저장 프로시 저는 호출 sp_start_job을 시작하거나 매 분마다 폴링을 피하기 위해 필요에 따라 동적으로 작업을 작성하기 위해 호출 할 수 있지만이 경우 복잡성은 서비스 브로커보다 단순하지 않을 수 있습니다.
Martin Smith

@MartinSmith 실제로이 두 번째 저장 프로 시저에 대한 작업 설정이 이미 있습니다. 첫 번째 프로 시저 번호와 올바르게 동기화되지 않는 문제가 발견 될 때까지 야간에 실행 되었기 때문입니다. 첫 번째 저장 프로 시저에서 작업을 시작하면 비동기식으로 실행되고 SP에서 즉시 반환됩니까?
Rachel

@Rachel-그렇습니다. sp_start_job즉시 반환합니다. 그래도 필요한 권한을 기억할 수 없습니다.
Martin Smith

1
큰 보안 허점을 열지 않으려면 다른 절차 / 데이터베이스에서 작업을 시작하는 것은 상당히 복잡한 문제입니다. Erland Sommarskog에는 결합해야 할 다양한 기술에 대한 기사가 있습니다. sommarskog.se/grantperm.html 그러나 완전한 해결책은 없습니다.
Sebastian Meine

1

다른 가능성은 감사 테이블이 완료 될 때 첫 번째 저장 프로 시저가 감사 테이블에 쓰도록하고 감사 테이블이 작성 될 때 두 번째 저장 프로 시저를 시작하는 감사 테이블에 트리거를 배치하는 것입니다. 지속적으로 폴링하거나 추가 SQL Server 에이전트 작업이 필요하지 않습니다.


3
첫 번째 저장 프로시 저는 감사 테이블에 대한 삽입이 완료 될 때까지 반환되지 않으며 트리거 실행이 완료 될 때까지 (두 번째 저장 프로 시저에 대한 호출 포함)
Martin Smith

1
이미 트리거를 사용하여 살펴 보았지만 트리거는 비동기식이 아닌 INSERTor UPDATE문으로 동기식으로 실행 되므로 Martin은 첫 번째 프로 시저가 두 번째 프로 시저가 리턴을 완료 할 때까지 대기하는 것으로 여전히 정확합니다.
Rachel
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.