この記事では、Oracle に関する関連知識を紹介します。Oracle データベースを開発していると、頻繁に操作される Oracle データ テーブルや、Oracle ロック テーブルが登場します。私が見つけたものを紹介します。 Oracle ロック テーブル ソリューションに関する関連情報。皆様のお役に立てば幸いです。
推奨チュートリアル: 「Oracle ビデオ チュートリアル 」
頻繁に発生するテーブル ロックやロック タイムアウトについては、誰もがよく知っていると思います。 DML ステートメントでは、その理由はデータベースの排他ロック メカニズムです。DML ステートメントが実行されると、トランザクションがコミットまたはロールバックされるか、現在のセッションが強制的に終了されるまで、テーブルまたは行のデータはロックされます。
私たちのアプリケーション システムでは、SQL の実行が遅く、タイムアウトがない (SQL が何らかの理由で実行に失敗し (Spoon ツールがデータ抽出とプッシュを行う) 場合)、テーブル ロックが発生する可能性が高くなります。リソースを解放しないでください) したがって、効率的な SQL を作成することが特に重要です。テーブル ロックが発生する可能性がある他の状況もあり、これは同時実行性が高いシナリオです。同時実行性が高いことによって引き起こされる問題は、Spring トランザクションによってデータベース トランザクションがコミットされなくなり、デッドロックが発生することです (現在のトランザクションは他のトランザクションがロックを解放するのを待っています)リソース)!したがって、例外 java.sql.SQLException: ロック待機タイムアウトを超過しました; がスローされます。
それでは、ロック テーブルまたはロック タイムアウトを解決するにはどうすればよいでしょうか?一時的な解決策は、ロック リソースを競合しているテーブルまたはステートメントを見つけて、現在のセッションまたはセッションを直接終了し、ロック リソースを強制的に解放することです。たとえば、
1. セッション 1 は特定のデータを変更しますが、トランザクションは送信せず、セッション 2 はコミットされていないトランザクションのレコードをクエリします
2. セッション 2 は
を変更しようとします。コミットされていないトランザクションを変更するレコードは、他のトランザクションが変更されるまで待機状態になることがわかります。パーティはロック リソースを解放するか、セッション 1 を強制的に閉じます。これは、Oracle が行レベルのロックを達成していることも示しています。
これはテーブル ロックの状況を簡単にシミュレーションしたものですが、セッション 1 によって発生したテーブル ロックであることが一目でわかります。実際の開発でこのような状況に遭遇した場合、SQL を使用してロック リソースを競合するテーブルやステートメントを直接見つけ出し、リソースを強制的に解放することが一般的です。 !
3. セッション 3 は、リソースを競合するテーブルまたはステートメントをクエリし、リソースを強制的に解放します。
-- 查询未提交事务的session信息,注意执行以下SQL,用户需要有DBA权限才行 SELECT L.SESSION_ID, S.SERIAL#, L.LOCKED_MODE AS 锁模式, L.ORACLE_USERNAME AS 所有者, L.OS_USER_NAME AS 登录系统用户名, S.MACHINE AS 系统名, S.TERMINAL AS 终端用户名, O.OBJECT_NAME AS 被锁表对象名, S.LOGON_TIME AS 登录数据库时间 FROM V$LOCKED_OBJECT L INNER JOIN ALL_OBJECTS O ON O.OBJECT_ID = L.OBJECT_ID INNER JOIN V$SESSION S ON S.SID = L.SESSION_ID WHERE 1 = 1
クエリの結果は次のとおりです。
#リソースの解放を強制します。最初の 2 つのフィールドのみが役立ちます。たとえば、
-- 强制 结束/kill 锁表会话语法 ALTER SYSTEM KILL SESSION 'SESSION_ID, SERIAL#'; -- 强制杀死session1,让session2可以修改id=5的那条记录 ALTER SYSTEM KILL SESSION '34, 111';セッション 1 を強制終了した後、セッション 2 の実行に注意してください。 session2 の待機が終了し、すぐに実行されることがわかります。誰もが疑問を持っていると思います。session_id は 29 と 34 です。セッション 1 とセッション 2 のどちらに属しているのかを判断し、セッション 2 が DML ステートメントを正常に実行できるようにセッション 1 を確実に強制終了するにはどうすればよいですか?実際には、こちらも非常に簡単です ここでの判断方法は session1 が更新は行うがトランザクションはサブミットしないという方法です まずは上記の SQL を使ってコミットされていないトランザクションのセッション情報を問い合わせます この時見つかった情報はセッション1の。 推奨チュートリアル: 「
Oracle ビデオ チュートリアル 」
以上がOracle ロック テーブル ソリューションの詳細なグラフィックとテキストの説明の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。