障害系のテストをするときにテーブルにロックをかける方法。
DB2コマンド(db2cmd)を起動して以下のSQLを実行する。
1.更新ロック(行単位)
トランザクションA(ロックをかける側)
DB2コマンドを起動して以下のSQLを実行する。
トランザクションA(ロックする側)
-- 最初にDB2のみ打ち込んで対話モードにする。
db2
connect to データソース名 user ユーザー名 using パスワード
-- 自動コミットをOFFにする。
update command options using c off
select * from テーブル名 where key = '111' for update with rs
-- ここまでの実行で key = '111' の行に更新ロックがかかるので、ロックされる側のトランザクションBを実行する。
-- コミットされるまでロックは続くので、トランザクションB(ロックで待たされる側)のテストが終わったら最後にコミットまたはロールバックでロック解除を忘れずに。
commit
トランザクションB(ロックで待たされる側)
トランザクションAで行に更新ロックがかかったら、ロックされる側のトランザクションBを実行する。
トランザクションB(ロックで待たされる側)
connect to データソース名 user ユーザー名 using パスワード
update テーブル名 set カラム名 = '222' where key = '111'
-- トランザクションAにより key = '111' の行に更新ロックがかかっているため、トランザクションBはここでロック待ち状態となる。
2.更新ロック(テーブル単位)
トランザクションA(ロックをかける側)
DB2コマンドを起動して以下のSQLを実行する。
トランザクションA(ロックする側)
-- 最初にDB2のみ打ち込んで対話モードにする。
db2
connect to データソース名 user ユーザー名 using パスワード
-- 自動コミットをOFFにする。
update command options using c off
lock table テーブル名 in share mode
-- ここまでの実行でテーブルに更新ロックがかかるので、ロックされる側のトランザクションBを実行する。
-- コミットされるまでロックは続くので、トランザクションB(ロックで待たされる側)のテストが終わったら最後にコミットまたはロールバックでロック解除を忘れずに。
commit
トランザクションB(ロックで待たされる側)
トランザクションAでテーブルに更新ロックがかかったら、ロックされる側のトランザクションBを実行する。
トランザクションB(ロックで待たされる側)
connect to データソース名 user ユーザー名 using パスワード
update テーブル名 set カラム名 = '222'
-- トランザクションAによりテーブルに更新ロックがかかっているため、トランザクションBはここでロック待ち状態となる。
3.排他ロック(テーブル単位)
トランザクションA(ロックをかける側)
DB2コマンドを起動して以下のSQLを実行する。
トランザクションA(ロックする側)
-- 最初にDB2のみ打ち込んで対話モードにする。
db2
connect to データソース名 user ユーザー名 using パスワード
-- 自動コミットをOFFにする。
update command options using c off
lock table テーブル名 in exclusive mode
-- ここまでの実行でテーブルに排他ロックがかかるので、ロックされる側のトランザクションBを実行する。
-- コミットされるまでロックは続くので、トランザクションB(ロックで待たされる側)のテストが終わったら最後にコミットまたはロールバックでロック解除を忘れずに。
commit
トランザクションB(ロックで待たされる側)
トランザクションAでテーブルに排他ロックがかかったら、ロックされる側のトランザクションBを実行する。
トランザクションB(ロックで待たされる側)
connect to データソース名 user ユーザー名 using パスワード
select * from テーブル名
-- トランザクションAによりテーブルに排他ロックがかかっているため、トランザクションBはここでロック待ち状態となる。
4.テーブルアクセス中にエラーを発生させる
上記1〜3のいずれかの方法でロック待ち状態の間に、テーブルスペースを排他モードで静止してエラーを発生させる。
トランザクションA(ロックをかける側)
トランザクションA(ロックする側)
-- トランザクジョンBがロック待ちの間にQUIESCEコマンドを実行し、テーブルスペースを排他モードで静止する。
QUIESCE TABLESPACES FOR TABLE テーブル名 EXCLUSIVE
-- トランザクションBでエラーが発生する。
-- テストが終わったら解除を忘れずに。
QUIESCE TABLESPACES FOR TABLE テーブル名 RESET
トランザクションB(ロックで待たされる側)
トランザクションBでは以下のようなエラーが発生する。
トランザクションB(ロックで待たされる側)
-- 更新ロックの場合
DB21034E コマンドが、有効なコマンド行プロセッサー・コマンドでないため、 SQL ステートメントとして処理されました。 SQL 処理中に、次のエラーが返されました。
SQL0911N デッドロックまたはタイムアウトのため、現在のトランザクションが ロールバックされました。 理由コード "2" SQLSTATE=4001
-- 排他ロックの場合
SQL0290N 表スペース・アクセスが許されていません。 SQLSTATE=55039