0

クエリを停止(強制終了)することに関して疑問が生じました。

サブスクライバーが複製するデータの量を変更する手順があります(詳細はわかりませんが、会社によってすでに実装されている機能です)。トランザクション内であるため、完了していない場合はロールバックでは、この手順を実行している間、すべてのサブスクライバーのレプリケーションがブロックされます。そのため、レプリケートするサブスクライバーの数が少なくなるか、まったくない夜間にこの操作を実行します。週末なので、手続きの実行を終了したいのですが(金曜日の午後10時)、手続きが終了しない場合、たとえば土曜日の午前6時に、手動で手続きを停止するためにオフィスに行く必要がない場合は、ロールバックしたいと思います。 。

午後10時に実行するように設定するのは簡単です。

waitfor time '22:00'

同じクエリでは、「シーケンシャル」であるため、クエリ全体を停止できるスクリプトにはできないことを認識していますが、他のクエリタブを開く方法はありますか?仕事を作ることが唯一の解決策ではないことを願っています(それが解決策である場合)。

返信ありがとうございます。

4

1 に答える 1

0

これを処理する最も簡単な方法は、実行時間の長いプロセスをジョブに入れることです。ワークステーションからサーバーへの確実にアクティブなネットワーク接続を備えたManagementStudioのオープンインスタンスは必要ありません。ジョブは一度に1つのインスタンスしか実行できないため、実行中の実際のプロセスを特定する作業がはるかに簡単になります。仕事(そしてそれに応じてそれに対処する)。

それで、私があなたを納得させたとしましょう、そしてあなたは金曜日の夜の午後10時に実行される予定の「私が殺したい仕事」と呼ばれる仕事を持っています。次のストアドプロシージャは、別のジョブとして、土曜日の午前6時にスケジュールするか、手動で呼び出すことができます。

CREATE PROCEDURE dbo.Kill_Job_I_Wanna_Kill
AS
BEGIN
  SET NOCOUNT ON;

  DECLARE @id UNIQUEIDENTIFIER;

  -- since the job could be dropped and re-created:
  SELECT @id = job_id
    FROM msdb.dbo.sysjobs
    WHERE name = 'Job I wanna kill';
  -- note that it could also be renamed, so you'll have to
  -- decide how to properly identify this job in the long run

  DECLARE @t TABLE
  (
    ID VARBINARY(32), rd INT, rt INT, nrd INT, 
    nrt INT, nrs INT, rr INT, rs INT, rsID SYSNAME, 
    Running BIT, cs INT, cra INT, [state] INT
  );

  -- note that this XP is undocumented and unsupported!
  INSERT @t EXEC master.dbo.xp_sqlagent_enum_jobs 1, 'sa', @id;

  IF EXISTS (SELECT 1 FROM @t WHERE Running = 1)
  BEGIN
    PRINT 'Cancelling job!';
    EXEC msdb.dbo.sp_stop_job @job_id = @id;
  END
  ELSE
  BEGIN
    PRINT 'Job is not running!'
  END
END
GO

ジョブが正常に強制終了されると、手動で呼び出された場合はプリントアウトとして、スケジュールされた場合はジョブステップ履歴に以下が表示されます。

Cancelling job!
Job 'Job I wanna kill' stopped successfully.

さて、他の問題が発生する可能性があります。ロールバックには、その時点に到達するのにかかった時間と同じくらい(またはそれ以上)かかる場合があります。それはすべて、実行時間の長いプロセスが何をしているかによって異なります(インデックスを再構築/再編成していると仮定します)。

于 2012-05-18T18:38:38.977 に答える