1

私の目標は次のとおりです。

  • 1つの永続的なデータベース接続とトランザクション。データを挿入/更新し、すべての作業が完了したときにコミットまたはロールバックできます。

  • 「随意」は、持続的接続とセッション状態を共有しない無関係な接続を開きました。つまり、古いデータを「見る」ことを意味します。これらの接続は、書き込みではなく、読み取りのみが必要です。

完全に新しい接続を開こうとしましたが、持続的接続によって行われた変更が表示されます。これを達成することは可能ですか?

注:すべての接続に同じOracleユーザー名/パスワードを使用しています。

注2:Toad(Oracle DB用のソフトウェア)は、コミットされるまで持続的接続によって行われた変更を「認識」しません。ロールバックされた場合、データベースには表示されません。コミットされた場合は表示されます。その部分は正常に機能します。アプリケーションから開かれた他の接続が、コミットされる前にそれらを認識しているだけです。

表示されるべきではない変更を表示する接続のコードは次のとおりです。

using (OracleConnection readConnection = new 
       OracleConnection(Settings.OracleConnectionString))
{
    readConnection.Open();

    using (OracleCommand command = new OracleCommand(lastOracleRowQuery, 
                                                     readConnection))
    {
        using (OracleDataReader reader = command.ExecuteReader())
        {
            if (reader.Read())
            {
                for (int i = 0; i < reader.FieldCount; i++)
                    compareValues.Add(reader.IsDBNull(i) ? 
                        null : 
                        reader.GetValue(i));
            }
        }
    }
}

これは、別のOracleConnectionが開いていて、その接続を使用するトランザクションがあるときに発生します。ただし、readConnectionは完全に無関係であるべきではありませんか?

この読み取りの結果は、Toadで同じクエリを同時に使用した場合には表示されない結果を示します。

解決しました

どうやら、Oracleは、テーブルの作成が失敗した場合でも、「CREATE TABLE」でセッションをコミットし、何もせず、例外をスローします。私はこの振る舞いを予期していなかったので、これが私を混乱させたものです。最初にすべてのテーブル作成を行うと、すべてが機能し始めました。テスト中に実際にテーブルが作成されていなかったので、それが問題だとは思いませんでしたが、コードをクリーンアップして最初に移動すると、すべてが自動的に修正されました。

しかし、Toadで何が起こっていたのかはまだわかりません。間違えたのかもしれません。または、私がまだ気付いていないバグが他にもあります。:D

4

1 に答える 1

0

System.Transaction.TransactionScope を使用している場合、スコープ内で作成されたすべての接続は単一のトランザクションとして扱われるため、永続的な接続によって作成されたデータは読み取り接続に表示されます。

スコープ オプションを TransactionScopeOption.Suppress として現在のスコープ内に新しい TransactionScope を作成し、そのスコープ内で読み取り接続を作成し、その新しいスコープで読み取り操作を実行する必要があります。コードは次のようになります。

//Outer Transaction        
using (TransactionScope t = new TransactionScope())
{
        //Create persistence connection and command
        // Execute persistence commands
        //Inner scope to suppress the outer transaction
    using (TransactionScope t1 = new TransactionScope(TransactionScopeOption.Suppress))
    {
        //create read connection
        // Execute read operation
    }
    //continue with write operation
}
于 2012-06-26T11:44:32.607 に答える