SET CHAINED command not allowed within multi-statement transaction.(zz)


Sybase ASEの実用化において、特にASE+
J 2 EE ?アプリケーションでは、より容易に現れる
SET CHAINED command not allowed within multi-statement transaction.の異常(バージョン15.0.1まで、ASEは異常メカニズムをサポートしていないが、本論文では便宜上、「異常」という言葉を統一).一部の開発者はSybaseデータベースの問題だと考えています.settAutoCommit()メソッドを複数回呼び出す問題があると考えられています.ある開発者は、jConnectの問題だと考え、jConnectのコードからこの異常を直接遮断することもある.
しかし、SET CHAINED異常バックグラウンドはどのように発生しますか?
  
一、データベース層
まず、見てみましょう
set chained.次のテキストクリップは『ASE 12.5.2 Reference Manual:Commands』から抜粋され、Page 430:
chained
begins a transaction just before the first data retrieval or data modification
statement at the beginning of a session and after a transaction ends. In
chained mode, Adaptive Server implicitly executes a begin transaction
command before the following statements: delete, fetch, insert, lock table,
open, select, and update. You cannot execute set chained within a transaction.
この段落から分かるように、set chained onの後、delete、fetch、insert、lock table、open、select、update文は自動的にトランザクションを開始し、commit/rollbackを明確に呼び出すことを明示的に完了する必要があります.また、トランザクションではchainedモードの設定は許可されません.
次のsqlコード・スライスでは、SET CHAINEDエラー情報がデータベース・レイヤ上でどのように生成されるかを説明します.
1> set chained on
2> go
1> set chained on
2> go
1> begin tran
2> go
1>
  
set chainedを複数回呼び出すと異常は発生しないようです.次に、
1> set chained on
2> go
Msg 226, Level 16, State 1:
Server 'FLYBEAN', Line 1:
SET CHAINED command not allowed within multi-statement transaction.
1> set chained off
2> go
Msg 226, Level 16, State 1:
Server 'FLYBEAN', Line 1:
SET CHAINED command not allowed within multi-statement transaction.
1>
は、トランザクション環境でset chainedを呼び出すと異常が発生することを明らかにしています.このマニュアルでも明確に指摘されています.しかし、なぜ前のセグメントでset chainedを2回連続して呼び出すと異常が発生しないのでしょうか.ドキュメントの次の文に注意してください.
Adaptive Server implicitly executes a begin transaction command before the following statements: .
データベース接続を再構築し、最初から次のようにします.
1> set chained on
2> go
1> select 1
2> go
-----------
1
(1 row affected)
1> set chained on
2> go
Msg 226, Level 16, State 1:
Server 'FLYBEAN', Line 1:
SET CHAINED command not allowed within multi-statement transaction.
1> set chained off
2> go
Msg 226, Level 16, State 1:
Server 'FLYBEAN', Line 1:
SET CHAINED command not allowed within multi-statement transaction.
1>
select 1を実行する前に、データベースは自動的にトランザクションを開始するので、set chainedを実行することはできません.次に、暗黙的に開始されたトランザクションを完了します.
1> rollback
2> go
1> set chained off
2> go
1>
  
二、J 2 EE層
J 2 EEアプリケーションでは、ConnectionのsetAutoCommit+commit()/rollback()を使用してトランザクションを管理する軽量レベルのデータ・アクセス・レイヤが実装されています.jConnectの逆コンパイルとspt_mdaデータの解析から、settAutoCommit(true)=SET CHAINED OFF;settoAutoCommit(false)=SET CHAINED ON、settoAutoCommit()メソッドの呼び出し時に実際に発生するインタラクションをシーケンス図で示します.
SET CHAINED command not allowed within multi-statement transaction.
一方,J 2 EEアプリケーションでは接続プールを採用することが多い.接続を呼び出します.close()メソッドの場合、実際には接続を閉じるのではなく、接続をプールに回収します.接続の初期状態がchained offであると仮定します.接続を取得した後に接続を呼び出すsetAutoCommit(false)メソッドを適用してトランザクションを開始し、トランザクションが完了していない場合にclose()メソッドでプールに戻ると、接続が次回setAutoCommit(false)メソッドに呼び出されると例外が放出されます.次の図を参照してください.
上記の解析により、この例外の原因が理解されると、setAutoCommit(false)が呼び出された後、select文が1つ実行された場合でも、トランザクションを表示的に完了する必要があるという例外を回避することが容易になります.同時に、接続を閉じる前にsettAutoCommit(true)を明示的に呼び出す必要があります.面倒だと思っているプログラマーもいるかもしれませんが、「壁を越えて趙に帰る」ことが資源借用者の義務であることを忘れないでください.