古いシステムのマイグレーション中です。とは言え、古すぎて、いろいろあれですが。
○ Delphi5 + AnyDAC 1.12
× Delphi5 + FireDAC 7.0.1.3119
症状
FireDAC において、StartTransaction後、TADQuery を使用して
1)SAVEPOINT HOGEHOGE、
2)ROLLBACK TO SAVEPOINT HOGEHOGE
を2回繰り返すと、2)で「ORA-01086 セーブポイント HOGEHOGE は、
このセッションで設定されていないか、無効です」が発生する。
AnyDACでは、発生しない。
FireDAC の、StartTransaction、Rollbackでは、SAVEPOINTをエミュレート
してくれるので、ネストして StartTransactionとRollbackを使用しておけば、
上記のSQLと同じSQLが処理されているようですが、ORA-01086 が
発生しないのです。
元々BDEを利用したアプリで、BDE→AnyDAC→FireDACと順に入れ替え中。
(今後Delphiも順に上げて、Ansi版最終の2007でとりあえず一区切り)
上記のとおり、FireDACのメソッドを使用することが回避策ですが、
通常のQueryで処理できないのがちょっと腑に落ちないので、なにか情報を
ご存知の方は教えて頂きたいと思います。
追記
StartTransaction
Query.SQL:SAVEPOINT HOGEHOGE
Query.SQL:ROLLBACK TO SAVEPOINT HOGEHOGE
Query.SQL:SAVEPOINT HOGEHOGE
Query.SQL:ROLLBACK TO SAVEPOINT HOGEHOGE //ここで例外発生
Rollback
------------------------
以下は正常動作
StartTransaction
StartTransaction //SAVEPOINT SP_2 を確認
Rollback //ROLLBACK TO SAVEPOINT SP_2 を確認
StartTransaction //SAVEPOINT SP_3 を確認
Rollback //ROLLBACK TO SAVEPOINT SP_3 を確認
Rollback
--------------------------
例外発生後は、SAVEPOINTの名前を変更しても効果ありません。
解決です。
TADConnection(or TFDConnection)
TxOptions.AutoCommit のデフォルトがTrueになっていたことが原因でした。
Falseに変更したところ、ExecSQLでSAVEPOINTの制御を行っても、例外が
発生せずに、正常に処理されることを確認しました。
参考URL
http://docwiki.embarcadero.com/Libraries/Berlin/ja/FireDAC.Stan.Option.TFDTxOptions.AutoCommit
自アプリケーションでは、明示的なトランザクション制御を行っています。
このとき、FireDACによる自動トランザクション管理は無効になるようですが、
どこかのタイミングで、自動トランザクションに戻ったりしたのかもしれません。
ツイート | ![]() |