MSSQLで開かれたトランザクションが長すぎるとどのような影響がありますか?


11

DBでトランザクションを開始し、それをコミットまたはロールバックするのを忘れた場合、どうなるのかと思っています。サーバーはダウンしますか?3日間放置したとしましょう。

他のユーザーが閉じられていないトランザクションがあることを知らなかったと仮定してそれを使用しているユーザーもいます(ユーザーがデータベースにデータを挿入していると仮定しましょう)。このアクションの結果は何ですか?

回答:


14

トランザクションを単独で開いても、ほとんど影響はありません。シンプルな

BEGIN TRANSACTION
-- wait for a while, doing nothing
-- wait a bit longer
COMMIT

最悪の場合、ステータス値の数バイトを保持します。大きな問題ではない。

ほとんどのプログラムはトランザクション内で実際の作業を行いますが、これは別の問題です。トランザクションのポイントは、同じデータベースに同時に書き込む他のユーザーがいるにもかかわらず、データベース内のいくつかのファクトが同時に真であることを確認できるようにすることです。

銀行口座間での送金の標準的な例を見てみましょう。システムは、ソースアカウントが存在し、十分な資金があり、デスティネーションアカウントが存在し、借方と貸方の両方が発生するか、どちらも発生しないことを確認する必要があります。他のトランザクションが発生している間、おそらくこれら2つのアカウント間でも、これを保証する必要があります。システムは、関係するテーブルをロックすることでこれを保証します。どのロックが使用され、他の人の作業のどれだけの量が表示されるかは、トランザクション分離レベルによって制御されます

そのため、多くの作業を行うと、ロックを保持しているオブジェクトを待機している他のトランザクションがキューに入る可能性が高くなります。これにより、システムの全体的なスループットが低下します。最終的にはタイムアウト制限に達して失敗しますが、これはシステム全体の動作の問題です。オプティミスティックな分離レベルを使用すると、他の人の作業が原因でコミットしようとしたときにトランザクションが失敗する場合があります。

ロックを保持すると、システムリソースが消費されます。これは、システムが他の要求を処理するために使用できないメモリであり、スループットを低下させます。

多くの作業が実行されている場合、システムはロックのエスカレーションを実行することを選択できます。個々の行をロックする代わりに、テーブル全体がロックされます。その後、より多くの同時ユーザーが影響を受け、システムのスループットがさらに低下し、アプリケーションへの影響が大きくなります。

データの変更は、それらを保護するロックと同様にログファイルに書き込まれます。これらは、トランザクションがコミットされるまでログから消去できません。したがって、トランザクションが非常に長いと、ログファイルが膨張し、関連する問題が発生する可能性があります。

現在の作業がtempdbを使用している場合、これは大きなワークロードの可能性が高いため、そこにあるリソースはトランザクションの終了まで拘束される可能性があります。極端な場合、これにより他のタスクが失敗する可能性があります。これは、他のタスクに十分なスペースがないためです。不十分にコード化されたUPDATEがtempdbを埋めたため、レポートのSORTに十分なディスクが残っていないため、レポートが失敗する場合がありました。

トランザクションをROLLBACKすることを選択した場合、またはシステムが失敗して回復した場合、システムが再び使用可能になるまでにかかる時間は、実行された作業量によって異なります。トランザクションを開いているだけでは、回復時間には影響しません。それは、実行された作業量です。トランザクションは開いていたが、1時間アイドル状態だった場合、回復はほぼ瞬時に行われます。その時間に絶えず書き込みを行っていた場合、経験則では、回復時間も約1時間になります。

ご覧のとおり、長いトランザクションには問題があります。OLTPシステムのベストプラクティスは、ビジネストランザクションごとに1つのデータベーストランザクションを持つことです。頻繁なコミットを伴うブロック単位のバッチワークプロセス入力、および再起動ロジックのコーディング。通常、単一のDBトランザクション内で数千のレコードを処理できますが、これは同時実行性とリソース消費についてテストする必要があります。

他の極端に行きたくなり、トランザクションとロックを完全に避けようとしないでください。データ内で一貫性を維持する必要がある場合(およびデータベースを使用する理由)、分離レベルとトランザクションは非常に重要な目的を果たします。オプションについて学び、アプリケーションの各部分について、並行性と正確性のバランスを決定します。


たとえ3日間開いていても?
JanLeeYu

はい、3日間でも。重要なポイントは、TXが開いている時間だけでなく、TXが開いている間に行われた作業量です。もちろん、DBAとして、トランザクションの所有者に、なぜ長い間開いている必要があるのか​​を尋ねることができます。DBAチームを運営したとき、30分以上開いていたTXをすべて記録し、所有者と会話しました。
マイケルグリーン

OK。素晴らしい説明をありがとう。誰もが素晴らしいことをしましたが。
JanLeeYu

なんと安relief感...答えてくれてありがとう。
JanLeeYu

「UPDATEが正しくコーディングされていません」はい。これを見た。一部の名前を修飾せず、1 = 1のような動作を引き起こすループ内の更新ステートメント。ループの繰り返しごとにテーブル全体を更新しました(これにより、これらの行のほとんどにも誤ったデータが配置されます)。
jpmc26

6

最大の結果は、トランザクションで使用されるオブジェクトのブロックです。特に、ユーザーがデータを挿入していると仮定すると、その長時間実行されるトランザクションには、よく使用されるテーブルのSELECTステートメントが含まれる可能性があります。ユーザーの更新ステートメントは、更新または挿入を完了するために必要なロックを取得できない場合があります。

発生する可能性のある二次的なことは、ログファイルのアクティビティです。たとえば、大きなデータセットを更新している場合、トランザクションが使用しているログの一部は、そのトランザクションの間アクティブに保持されます。トランザクションがコミットまたはロールバックされるまで、ログのその部分を再利用することはできません。非常にアクティブなOLTPシステムを使用しているシナリオでは、これによりログファイルが急速に大きくなり、ストレージデバイスがいっぱいになる可能性があります。


たとえば、トランザクションを作成した人がサーバーから切断された場合、彼/彼女は再びサーバーにログインしてトランザクションを閉じることができますか?
JanLeeYu

トランザクションがMSDTCを使用した環境にあった場合、孤立したトランザクションである可能性があります。その場合、ユーザーは自分でそれを閉じることができなくなります... DBAはそれを処理するために介入する必要があります。それ以外では、通常、SQL Serverが切断したときにトランザクションがキャンセルされるのを確認する必要があります。

その場合、管理者はトランザクションを正しく閉じることができますか?
JanLeeYu

私はその1つに答えることができません、それはすべて依存しています。サーバーを再起動する必要がある場合や、インスタンスがセカンダリノード/レプリカにフェールオーバーする場合があります。

4

不完全なトランザクションは多数のロックを保持し、ブロッキングを引き起こす可能性があります

クエリがタイムアウトするか、トランザクションを完了するためにCOMMITまたはROLLBACKステートメントを発行せずにトランザクションの途中でバッチがキャンセルされるため、トランザクションが完了しない場合、トランザクションは開いたままになり、そのトランザクション中に取得されたすべてのロックが続行されます開催される。同じ接続で実行される後続のトランザクションはネストされたトランザクションとして扱われるため、これらの完了したトランザクションで取得されたすべてのロックは解放されません。この問題は、ROLLBACKが実行されるまで、同じ接続から実行されるすべてのトランザクションで繰り返されます。その結果、多数のロックが保持され、ユーザーがブロックされ、トランザクションが失われ、予想とは異なるデータが生成されます。

ソース


たとえば、トランザクションを作成した人がサーバーから切断された場合、彼/彼女は再びサーバーにログインしてトランザクションを閉じることができますか?
JanLeeYu

SQL Serverは、接続が失われたことを認識すると、トランザクションをロールバックします。こちらdba.stackexchange.com/questions/47404/…をご覧ください。同じユーザーが再接続すると、別のセッションになるため、古いトランザクションを何らかの方法で「採用」することはできません。
マイケルグリーン
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.