0

odbc 経由で sybase に接続する Yii を使用して、ストアド プロシージャとマルチステートメント トランザクションで問題が発生しました。

トランザクション内でストアド プロシージャを実行しているときに発生した次のエラーを特定するには...

CDbCommand failed to execute the SQL statement: SQLSTATE[ZZZZZ]: <>: 7713 [Sybase][ODBC Driver][Adaptive Server Enterprise]Stored procedure 'myStoredProcedure' may be run only in unchained transaction mode. The 'SET CHAINED OFF' command will cause the current session to use unchained transaction mode. (SQLExecute[7713] at /builddir/build/BUILD/php-5.3.3/ext/pdo_odbc/odbc_stmt.c:254). The SQL statement executed was: exec myStoredProcedure 

次の非常に簡単なテストを試みました。

$connection=Yii::app()->db;
$transaction = Yii::app()->db->beginTransaction();
$sql="select 'Tranchained'=@@tranchained";  //0=off, 1=on
$command=$connection->createCommand($sql);
error_log('Chained Mode On or Off ='.$command->queryScalar());
$transaction->commit();

エラー ログには、チェーン モードのオンまたはオフ = 1 が表示されます。これは、トランザクションがチェーン モードをオンにしていることを意味します。これは、私がやるべきだと思っていたことの反対です。また、チェーン モードがこのトランザクションの外部でオフになっていることも確認したので、それをオンにしているのはトランザクションであると確信しています。

簡単な解決策は、次のコードをトランザクション内 (上部) に挿入して、トランザクション内で連鎖モードをオフにする SQL ステートメントを追加することです。

$sql='set chained off';
$command=$connection->createCommand($sql);
$command->execute();

そして、これは私の単純な例で機能します。ただし、複数ステートメントのトランザクションを使用しているため、実際のアプリケーションを使用すると機能せず、次のエラーが発生します。

CDbCommand failed to execute the SQL statement: SQLSTATE[ZZZZZ]: <>: 226 [Sybase][ODBC Driver][Adaptive Server Enterprise]SET CHAINED command not allowed within multi-statement transaction. (SQLExecute[226] at /builddir/build/BUILD/php-5.3.3/ext/pdo_odbc/odbc_stmt.c:254). The SQL statement executed was: set chained off 

私も試しました:

$connection->setAutoCommit(false);

無駄に

4

1 に答える 1

0

シンプルなソリューション。使用しないでください

Yii::app()->db->beginTransaction();

むしろこれを行います。これは実際に機能し、期待どおりに動作します

$sql='begin transaction'; //or commit transaction, or rollback transaction
$command=$connection->createCommand($sql);
$command->execute();

その場しのぎのクラスは、次のように作成できます (おそらく、これを行うためのより洗練された方法です)。

class SybaseDb {

    public function beginTransaction() {
        $connection=Yii::app()->db;
        $sql='
            begin transaction 
        ';
        $command=$connection->createCommand($sql);
        $command->execute();        
    }

    public function rollBack() {
        $connection=Yii::app()->db;     
        $sql='
            rollback transaction 
        ';
        $command=$connection->createCommand($sql);
        $command->execute();            
    }

    public function commit() {
        $connection=Yii::app()->db; 
        $sql='
            commit transaction 
        ';
        $command=$connection->createCommand($sql);
        $command->execute();        
    }   

}
于 2013-01-08T16:48:25.943 に答える