1

Oracle で奇妙な問題が発生しています。最初に (単純化された) コンテキストをいくつかスケッチします。

エンティティへのこのマッピングを検討してください。

public EntityMap()
{
    Table("EntityTable");
    Id(x => x.Id)
        .Column("entityID")
        .GeneratedBy.Native("ENTITYID").UnsavedValue(0);
    Map(x => x.SomeBoolean).Column("SomeBoolean");
}

そしてこのコード:

var entity = new Entity();
using (var transaction = new TransactionScope(TransactionScopeOption.Required))
{
    Session.Save(entity);
    transaction.Complete();
}

//A lot of code
if(someCondition)
{            
    using (var transaction = new TransactionScope(TransactionScopeOption.Required))
    {
        enitity.SomeBoolean = true;
        Session.Update(entity);
        transaction.Complete();
    }
}

このコードは数回呼び出されます。初めて次のクエリを生成します。

select ENTITYID.nextval from dual
INSERT INTO Entity
    (SomeBoolean, EntityID)
    VALUES  (0, 1216)
UPDATE Entity
    SET SomeBoolean = 1
    WHERE  EntityID = 1216

2 回目に呼び出されると、これらのクエリが生成されます (someConditionは false です) 。

select ENTITYID.nextval from dual
INSERT INTO Entity
    (SomeBoolean, EntityID)
    VALUES  (0, 1217)

そして今、トラブルが始まります。今後は、挿入ごとに正しい自動インクリメント値が使用されますが、更新では常に 1217 が使用されます。

select ENTITYID.nextval from dual
INSERT INTO Entity
    (SomeBoolean, EntityID)
    VALUES  (0, 1218)
UPDATE Entity
    SET SomeBoolean = 1
    WHERE  EntityID = 1217

そしてもちろん、これは私たちが望んでいることではありません。デバッグ中に Id の値を調べると、正しい自動インクリメント値が含まれています。どういうわけか、NHibernate の奥深くで、間違った is が WHERE 句に割り当てられています...

奇妙な点は、これが Oracle でのみ発生することです。NHibernate を MsSql に切り替えると、すべてがうまく機能します。

4

1 に答える 1

0

それで私は何が起こったのかを知りました。NHibernateは、バージョン1.xと2.xの間でデフォルトの接続リリースモードを変更しました。セッションが破棄されたときに接続を閉じる代わりに、各トランザクションの後に接続が閉じられるようになりました。ただし、トランザクションを手動で調整していたため、Oracleで問題が発生したようです。

この質問にはいくつかの追加情報があり、NHibernateドキュメントのこのエントリは、接続がどのように処理されるかも明確にします。

NHibernateの時点で、アプリケーションがSystem.Transactionsライブラリなどの.NET APIを介してトランザクションを管理する場合、ConnectionReleaseMode.AfterTransactionにより、NHibernateが1つのトランザクション中に複数の接続を開閉し、ローカルから分散への不要なオーバーヘッドとトランザクションの昇格につながる可能性があります。ConnectionReleaseMode.OnCloseを指定すると、従来の動作に戻り、この問題の発生を防ぐことができます。

このブログ投稿は、私が正しい方向を見た理由です。

于 2013-01-03T11:56:28.933 に答える