相关疑难解决方法(0)

NHibernate FlushMode自动不会在查找之前刷新

好吧,我看到一些帖子几乎要问同样的事情但是点数有点不同.

这是一个经典案例:我正在保存/更新一个实体,并且在同一个会话中,我试图通过FlushMode = Auto从数据库中获取它们(使用criteria/find/enumerable/etc).问题是:NHibernate在查询之前没有刷新更新,所以我从数据库中获取了不一致的数据.

有些人会说,"足够公平",正如文件所述:

此过程刷新默认情况下发生在以下几点:

  • 来自Find()或Enumerable()的一些调用
  • 来自NHibernate.ITransaction.Commit()
  • 来自ISession.Flush()

大胆的"一些调用"清楚地表明NH根本没有责任.但是,IMO在这里遇到了一致性问题,因为该文档还指出:

除非明确表示Flush(),否则绝对无法保证Session何时执行ADO.NET调用,只保证执行它们的顺序.但是,NHibernate确保ISession.Find(..)方法永远不会返回陈旧数据; 他们也不会返回错误的数据.

因此,如果我使用CreateQuery(查找替换)并过滤属性值为20的实体,NH可能不会返回值为30的实体,对吧?但这就是事实上发生的事情,因为Flush不应该自动发生.

public void FlushModeAutoTest()
{
    ISession session = _sessionFactory.OpenSession();
    session.FlushMode = FlushMode.Auto;

    MappedEntity entity = new MappedEntity() { Name = "Entity", Value = 20 };
    session.Save(entity);

    entity.Value = 30;
    session.SaveOrUpdate(entity);

    // RETURNS ONE ENTITY, WHEN SHOULD RETURN ZERO
    var list = session.CreateQuery("from MappedEntity where Value = 20").List<MappedEntity>();

    session.Flush();
    session.Close();
}
Run Code Online (Sandbox Code Playgroud)

毕竟:我错了,它是一个错误还是一个不可预测的功能所以每个人都必须打电话给Flush以确保它的工作?

谢谢.

菲利佩

nhibernate

6
推荐指数
1
解决办法
4934
查看次数

NHibernate 3.0:TransactionScope和Auto-Flushing

在NHibernate 3.0中,FlushMode.Auto仅在环境事务下运行时无效(即,无需启动NHibernate事务).应该是?

using (TransactionScope scope = new TransactionScope()) 
{
    ISession session = sessionFactory.OpenSession();
    MappedEntity entity = new MappedEntity() { Name = "Entity", Value = 20 };
    session.Save(entity);

    entity.Value = 30;
    session.SaveOrUpdate(entity);

    // This returns one entity, when it should return none
    var list = session.
               CreateQuery("from MappedEntity where Value = 20").
               List<MappedEntity>();
}
Run Code Online (Sandbox Code Playgroud)

(从这个相关问题无耻地偷走的例子)

在NHibernate的来源,我可以看到这就是它检查是否有正在进行中(在一个事务SessionImpl.AutoFlushIfRequired),但相关方法(SessionImpl.TransactionInProgress)不考虑环境事务-不像它的近亲ConnectionManager.IsInActiveTransaction,这确实考虑环境事务.

nhibernate flush transactionscope distributed-transactions nhibernate-3

6
推荐指数
1
解决办法
4826
查看次数

事务范围因Oracle中的BeginTransaction而失败:Connection已经是本地或分布式事务的一部分

使用OracleConnection与TransactionScope时出现这种奇怪的行为.如果我尝试在事务范围中使用connection.BeginTransaction(),我会得到简单优雅的InvalidOperationException:Connection已经是本地或分布式事务的一部分.

这是一些代码:

var trxOptions = new TransactionOptions();
 trxOptions.IsolationLevel = IsolationLevel.ReadCommitted;
 using (var transaction = new TransactionScope(TransactionScopeOption.Required,trxOptions))
            {

                var c = ConfigurationManager.ConnectionStrings["oracle_test"].ConnectionString;
                using (var oracle = new OracleConnection(c))
                {
                    oracle.Open();
                    using (var tr = oracle.BeginTransaction(System.Data.IsolationLevel.ReadCommitted))
                    {
                        var cmd = oracle.CreateCommand();
                        cmd.CommandText = "INSERT INTO simple_user VALUES('a')";

                        cmd.ExecuteNonQuery();
                        tr.Commit();
                    }
                }


        // now go to sql server and insert data
       transaction.Complete();
Run Code Online (Sandbox Code Playgroud)

}

如果我不使用BeginTransaction一切正常.有什么想法让它发挥作用?

PS:我在Sql Server上没有这样的问题.

编辑

谢谢你的答案,我想我应该添加一些编辑,以使我的问题清楚.

首先,我上面提供的代码是问题的证明.让我说我有两个DLL的MyProject.Oracle.dll和MyProject2.MsSql.dll,我想使用这些DLL中的方法,他们使用db.BeginTransaction().如果这些dll使用了TransactionScope,我的外部事务就不会成为问题.分配交易将在没有任何问题的情况下处理.但我不能改变dll中的代码.

为什么db.BeginTransaction()适用于SqlServer而不适用于Oracle?

c# oracle odp.net transactionscope

6
推荐指数
1
解决办法
1万
查看次数