Oracle(10gR2)でTransactionScopeを利用する際に、以下のエラーがでる場合があります。
"oramts.dllが見つかりません。"
このエラーが出た場合、以下の点を疑ってみてください。
マシンに、Oracle Services For Microsoft Transaction Service (OraMTS)がインストールされているかどうか?
OraMTSは、Oracle Clientをカスタムモードでインストールしないとインストールされません。
インストールすると、ORACLE_HOME/Binの下に以下のファイルが見つかります。
- oramts.dll
- oramts10.dll
このファイルが無いと、TransactionScopeブロック内でコネクションをOpenした時に落ちます。
逆に言うとこのファイルさえあれば動きます。
また、TransactionScopeブロックの外でコネクションをOpenし、そのコネクションを使用して
TransactionScope内で処理を行なっても、うまく動きますが、これは実はトランザクションに
参加していません。なので、処理が失敗し、TransactionScope.Completeメソッドが呼ばれない
状態だと通常ロールバックされるはずが、ロールバックされない状態となります。
具体的には、以下のようなコードの場合です。
[TestFixture()] public class TestClass{ OracleConnection _conn; [Setup()] public void SetUpMethod(){ _conn = new OracleConnection("Data Source=xxx;User Id=xxx;Password=xxx;Enlist=True"); } [TearDown()] public void TearDownMethod(){ _conn.Close(); } [Test()] public void TestMethod(){ using(TransactionScope tx = new TransactionScope()){ using(OracleCommand command = _conn.CreateCommand()){ command.CommandText = "insert into xxx (xxx) values (xxxx)"; Assert.AreEqual(1, command.ExecuteNonQuery()); tx.Complete(); } } } }
上記のコードの場合、例えば一意制約などで追加処理が失敗した場合、Completeメソッドは
よばれないままブロックを抜けますが、ロールバックはされません。しかも、この場合は
TransactionScopeクラスが管理するトランザクションに参加しないので、oramts.dllが
存在しない状態でも動作します。つまり、OraMTSがインストールされていない状態でも
見た目ちゃんと動いているように見えます。(これにハマリました・・・)