1

これが問題です。

tableA に挿入して、その新しい行 ID を取得する必要があります。その後、その ID を tableB に挿入する必要があります。tableB に挿入しようとしたときに外部キー例外が発生しないように、tableA への挿入後にコミットする必要があります。

ここで、tableB に挿入する関数で例外が発生した場合、try-catch ブロックが例外をキャッチすると、テーブルへの元の挿入がロールバックされることを理解しました。それはしていません。

どこかで間違えているのですが、どこかわかりません。ここで必要なことを達成する方法はありますか?

try
    {

        tableAinsert.ExecuteNonQuery();
        transaction.Commit();

        id= Int32.Parse(tableAinsert.Parameters["id"].Value.ToString());

        if (vsType == "I")
        {
            tableBinsert(vsType, eventId, id);
        }

    }
    catch (Exception err)
    {
         transaction.Rollback();
        throw (err);
    }
4

1 に答える 1

1

そこで、私の同僚が問題を指摘しました。

このような複数ステップの挿入をロールバックできるようにするには、同じ接続と同じトランザクションを使用する必要があるようです。また、トランザクションごとにコミットできるのは 1 つだけです。

これは、独自の接続コマンドとトランザクション コマンドを持つ各関数を変更して、最初に OracleConnection および OracleTransaction 引数を受け入れ、commit() コードとその他の関連行を削除する必要があることを意味します。

投稿したコードを修正すると、次のようになります

OracleConnection conn = new OracleConnection();
 // .... create your command, set the connection string, etc, etc
var transaction = conn.BeginTransaction();
cmd.Transaction = transaction;

try
{

    tableAinsert.ExecuteNonQuery();


    id= Int32.Parse(tableAinsert.Parameters["id"].Value.ToString());

    if (vsType == "I")
    {
        tableBinsert(vsType, eventId, id, conn, transaction);
    }

    transaction.Commit();  //Moved this commit to the end of the block

}
catch (Exception err)
{
     transaction.Rollback();
    throw (err);
}
于 2010-02-03T19:41:18.800 に答える