#blognavi
#blognavi
とりあえず、Firebirdは動くようになり、管理ツールも使えるようになった。というところで、気になったのは、行ロックの制御がどれくらいできるのかということだった。
DBで行ロックの制御がちゃんとできないとプログラム側での労力が大きい。
SQL Server でも ORACLEでも変わらないと思っている人も結構いるようだが、やはりDBの機能差は上位アプリを開発する上ではかなり影響する。ORACLEの機能を有効に使うことでだいぶコードは減るものだ。
という点の一つ大きいところがこのロック制御に他ならない。
SQL Server でも ORACLEでも変わらないと思っている人も結構いるようだが、やはりDBの機能差は上位アプリを開発する上ではかなり影響する。ORACLEの機能を有効に使うことでだいぶコードは減るものだ。
という点の一つ大きいところがこのロック制御に他ならない。
Firebirdへの接続
DBに接続。
SQL> connect "/opt/firebird/examples/employee.fdb" CON> user 'sysdba' password 'welcome'; Database: "/opt/firebird/examples/employee.fdb", User: sysdba
CUSTOMER表の構成を見る。
SQL> show table customer; CUST_NO (CUSTNO) INTEGER Not Null CHECK (VALUE > 1000) CUSTOMER VARCHAR(25) Not Null CONTACT_FIRST (FIRSTNAME) VARCHAR(15) Nullable CONTACT_LAST (LASTNAME) VARCHAR(20) Nullable PHONE_NO (PHONENUMBER) VARCHAR(20) Nullable ADDRESS_LINE1 (ADDRESSLINE) VARCHAR(30) Nullable ADDRESS_LINE2 (ADDRESSLINE) VARCHAR(30) Nullable CITY VARCHAR(25) Nullable STATE_PROVINCE VARCHAR(15) Nullable COUNTRY (COUNTRYNAME) VARCHAR(15) Nullable POSTAL_CODE VARCHAR(12) Nullable ON_HOLD CHAR(1) Nullable DEFAULT NULL CONSTRAINT INTEG_61: Foreign key (COUNTRY) References COUNTRY (COUNTRY) CONSTRAINT INTEG_60: Primary key (CUST_NO) CONSTRAINT INTEG_59: CHECK (on_hold IS NULL OR on_hold = '*') Triggers on Table CUSTOMER: SET_CUST_NO, Sequence: 0, Type: BEFORE INSERT, Active
CUSTOMER表を検索してみる。
SQL> select cust_no,customer from customer where cust_no=1001; CUST_NO CUSTOMER ============ ========================= 1001 Signature Design SQL>
ロックを発生させる。
TELNETでA,B2箇所からfirebirdに接続する。
Aで実行。
SQL> select cust_no,customer from customer where cust_no=1001 for update; CUST_NO CUSTOMER ============ ========================= 1001 Signature Design SQL>
Bで実行。ここでロックを発生させる。
SQL> select cust_no,customer from customer where cust_no=1001 for update; CUST_NO CUSTOMER ============ ========================= 1001 Signature Design SQL>
と、どちらもSELECTできてしまい、ロックがかからなかった。
次にUPDATE句で実行する。
Aで実行。
Aで実行。
SQL> update customer set contact_last='TEST' where cust_no=1001; SQL>
Bで実行。
SQL> update customer set contact_last='TEST' where cust_no=1001;
これでBではロックがかかっている為、WAITになる。
次に、SELECT FOR UPDATE句でのロックを再度確認。
「with lock」をつけることでロックをつけられた。
「with lock」をつけることでロックをつけられた。
SQL> select cust_no,customer from customer where cust_no=1001 for update with lock; CUST_NO CUSTOMER ============ ========================= 1001 Signature Design SQL>
これをBでも実行するとロックのためのWAITになる。
またBで1002を検索すると、ロックを取得できる。
またBで1002を検索すると、ロックを取得できる。
SQL> select cust_no,customer from customer where cust_no=1002 for update with lock; CUST_NO CUSTOMER ============ ========================= 1002 Dallas Technologies SQL>
これでUPDATE及びSELECT FOR UPDATEで行ロックがちゃんとかかる。
NO WAITのテスト。
次に、NO WAITのテスト。プログラムの中ではロック解除を待たずにエラーで返してくれる方が良い場合もある。ということで、ロックしているデータの場合は即エラーで返す設定を確認する。
Aで上記と同様でロックをかける。
Bで下記を実行。
Bで下記を実行。
SQL> set transaction no wait;
これでロック時にはWAITをかけずにエラーする。
SQL> select cust_no,customer from customer where cust_no=1001 for update with lock; CUST_NO CUSTOMER ============ ========================= Statement failed, SQLCODE = -901 lock conflict on no wait transaction -deadlock -update conflicts with concurrent update SQL>
デッドロックチェック
次にはデッドロックの場合どのようなエラーを返すか確認する。
Aで下記を実行。
SQL> set transaction wait; SQL> select cust_no,customer from customer where cust_no=1001 for update with lock; CUST_NO CUSTOMER ============ ========================= 1001 Signature Design
このとき、Bで下記を実行する。
SQL> set transaction wait; SQL> select cust_no,customer from customer where cust_no=1002 for update with lock; CUST_NO CUSTOMER ============ ========================= 1002 Dallas Technologies
これでAがCUST_NO=1001、BがCUST_NO=1002をそれぞれロックしている。
このときに、Bで下記を実行。
このときに、Bで下記を実行。
SQL> select cust_no,customer from customer where cust_no=1001 for update with lock;
これでBはロック待ち状態に入る。
Aでデッドロックを発生させる。
SQL> select cust_no,customer from customer where cust_no=1002 for update with lock;
これでデッドロック完成。すると1,2秒後に下記のエラーが発生。
CUST_NO CUSTOMER ============ ========================= Statement failed, SQLCODE = -913 deadlock -deadlock -update conflicts with concurrent update
上記でロック系の確認を一通りした。
フリーのDBということでロックについてはあまり期待していなかったが結構実用に耐えうるものと思えた。
フリーのDBということでロックについてはあまり期待していなかったが結構実用に耐えうるものと思えた。
カテゴリ: [Firebird] - &trackback() - 2005年09月05日 00:25:25