Do You PHP?    
Search Engine Optimization  php5 powerd  Valid XHTML 1.0!  Valid CSS!  このサイトのはてなブックマーク数 



last updated
2003/09/01

counter hits
since 1999/11/06


プロファイルを使った実行時間の制限

alertここにある情報はかなり古くなっており、正しくなくなっている可能性があります。掲載しているサンプルコードiなどは、最新のPHPでは動作しない、もしくは、別途設定・調整が必要になるかも知れません。情報を鵜呑みにせず、あなたの手を動かして、あなたの目で確認してください。

php-usersネタです。「実行中のSQLをタイムアウトさせてDBとの接続を切りたい」ということはPHP側から行うことは出来ませんが、Oracleのプロファイルを使用することで実現できるようです。

ユーザーリソースの制限を行うには、Oracleインスタンスのパラメータファイルで「RESOURCE_LIMIT = TRUE」を指定しOracleインスタンスの再起動を行うか、ALTER SYSTEMコマンドを使用してRESOURCE_LIMITをTRUEに変更する必要があります。

●プロファイルの作成とユーザーへの割り当て
SQL> ALTER SYSTEM SET RESOURCE_LIMIT = TRUE;

システムが変更されました。

SQL> 

プロファイルについての詳細説明はOracleマニュアルを参照していただくとして、今回は以下の手順でプロファイルの作成とユーザーへの割り当てを行いました。

  • 1セッション当たりの合計経過時間を1分に制限するプロファイルを作成
  • scottユーザーへの割り当て
●プロファイルの作成とユーザーへの割り当て
SQL> CREATE PROFILE connection LIMIT
  2  CONNECT_TIME 1;

プロファイルが作成されました。

SQL> ALTER USER scott PROFILE connection;

ユーザーが変更されました。

SQL> 

そして、以下のようなPHPスクリプトを実行してみます。

●profile.php

<?php
<h1>●ユーザープロファイルのテスト</h1>
<?php
    set_time_limit(0);
    $conn = OCILogon("scott", "tiger", "orcl");
    $stmt = OCIParse($conn,"INSERT INTO emp (empno) VALUES(1234) ");

    echo "start:" . time() . "<br>";
    $loop = 0;
    while (true) {
        OCIExecute($stmt, OCI_DEFAULT);
        $err = OCIError($stmt);
        if ($err) {
            echo "<pre>";
            print_r($err);
            echo "</pre>";
            break;
        }
        sleep(10);
        echo "loop:" . ++$loop . "<br>";
    }
    echo "finish:" . time() . "<br>";
?>
●実行結果
●ユーザープロファイルのテスト
start:1062333301
loop:1
loop:2
loop:3
loop:4
loop:5
loop:6
loop:7
loop:8
loop:9
loop:10
loop:11
loop:12
loop:13
loop:14
loop:15
loop:16
loop:17
loop:18
loop:19
loop:20

Warning: ociexecute(): OCIStmtExecute: ORA-02399: 最大接続時間を超えました。
ログオフ中です。 in /path/to/profile.php on line 10

Array
(
    [code] => 2399
    [message] => ORA-02399: 最大接続時間を超えました。ログオフ中です。

    [offset] => 0
    [sqltext] => INSERT INTO emp (empno) VALUES(1234)
)

finish:1062333501

Warning: Unknown(): failed to rollback outstanding transactions!:
ORA-01012: ログオンされていません。 in Unknown on line 0

Warning: Unknown(): _oci_close_session: OCISessionEnd: ORA-00022:
無効なセッションIDです。アクセスは拒否されました in Unknown on line 0  

結果を見ていただくと、確かに処理途中で接続を切られています。赤字の部分は、本来は文字化けして表示された部分です。

今回はOCIError関数でエラーを拾ってみましたが、Oracle側から強制的にログオフさせされているようです。が、なぜ200秒。。。?(^-^; まあ、実行時間が数分レベル以上な処理であれば、PHPではなく別の方法を考えた方が幸せになれる確率が高そうな気がしますが。。。(^-^;

memo[2003/09/01]Oracleのサポートサイトによると、どうやら設定した時間通りに制限がかかるようではないようです。

あと、今回のようなプロファイルを使用すると、どの接続もこの制限に引っかかってしまう可能性がありますので、処理系毎にOracleユーザーを切り替えるなどの必要がありそうです。



About This Site |  Privacy Policy |  Contact
Copyright © 1999 - 2003 by Hideyuki SHIMOOKA all rights reserved.