C# 刷新时返回旧数据

C# 刷新时返回旧数据,c#,asp.net-mvc,nhibernate,asp.net-core-mvc,C#,Asp.net Mvc,Nhibernate,Asp.net Core Mvc,我正在使用TransactionScope和nHibernate。为了处理嵌套事务,我与TransactionScope一起创建了一个助手类。我的会话工厂: public class SessionFactory { [ThreadStatic] private static ISessionFactory iSessionFactory; [ThreadStatic] protected static ISession

我正在使用TransactionScopenHibernate。为了处理嵌套事务,我与TransactionScope一起创建了一个助手类。我的会话工厂

 public class SessionFactory
    {
        [ThreadStatic]
        private static ISessionFactory iSessionFactory;
        [ThreadStatic]
        protected static ISession session;
        private static object syncRoot = new Object();

        private static void buildSessionFactory()
        {
            lock (syncRoot)
            {
                if (session == null)
                {
                    if (iSessionFactory == null)
                    {
                        Configuration configuration = new Configuration().Configure("hibernate.cfg.xml");
                        Assembly assembly = Assembly.GetCallingAssembly();
                        iSessionFactory = configuration.BuildSessionFactory();
                    }
                    if (session != null && session.IsOpen)
                        session.Dispose();
                    CurrentSessionContext.Bind(iSessionFactory.OpenSession());
                    session = iSessionFactory.OpenSession();
                }
            }
        }

        public static ISession OpenSession
        {
            get
            {
                if (session == null || !session.IsOpen)
                {
                    session = null;
                    buildSessionFactory();
                }
                return session;
            }
        }
    }
  public class TransactionScopeHelper : SessionFactory, iTransactionScopeHelper
    {
        public static int count = 0;
        public TransactionScope getTransactionScope()
        {
            if (count == 0)
            {
                if (session != null)
                    session.Clear();
            }
            count++;
            return new TransactionScope(TransactionScopeOption.Required);
        }

        public void complete(TransactionScope tx)
        {
            count--;
            if (count == 0)
            {
                session.Flush();
                session = null;
            }
            tx.Complete();
        }

        public void rollbackTransaction()
        {
            count = 0;
            session = null;
        }
    }
 public T getById(long id)
 {
  ISession session = SessionFactory.OpenSession;
  return session.Get<T>(id);
 }
配置文件名为hibernate.cfg.xml,它是:

<configuration>
  <hibernate-configuration xmlns="urn:nhibernate-configuration-2.2">
    <session-factory>
      <property name="connection.provider">NHibernate.Connection.DriverConnectionProvider</property>
      <property name="connection.driver_class">
        NHibernate.Driver.MySqlDataDriver
      </property>
      <property name="dialect">NHibernate.Dialect.MySQL55InnoDBDialect</property>
      <property name="connection.connection_string">connection string here</property>
      <property name="current_session_context_class">thread_static</property>
      <property name="show_sql">true</property>
      <property name="generate_statistics">true</property>
      <mapping assembly="assembly name here"/>
      <!-- Here -->
    </session-factory>
  </hibernate-configuration>
  <system.transactions>
    <machineSettings maxTimeout="00:00:60" />
  </system.transactions>
</configuration>
助手类仅在服务中使用,而不在存储库中使用 在服务中使用帮助器的示例:

public void updateCategory(CategoryDto category_dto)
{
 try
   {
    using (TransactionScope tx = transactionScopeHelper.getTransactionScope())
     {
      //works here
      transactionScopeHelper.complete(tx);
     }
   }
   catch(Exception)
   {
    transactionScopeHelper.rollbackTransaction();
    throw;
    }
}
存储库中的函数示例:

 public class SessionFactory
    {
        [ThreadStatic]
        private static ISessionFactory iSessionFactory;
        [ThreadStatic]
        protected static ISession session;
        private static object syncRoot = new Object();

        private static void buildSessionFactory()
        {
            lock (syncRoot)
            {
                if (session == null)
                {
                    if (iSessionFactory == null)
                    {
                        Configuration configuration = new Configuration().Configure("hibernate.cfg.xml");
                        Assembly assembly = Assembly.GetCallingAssembly();
                        iSessionFactory = configuration.BuildSessionFactory();
                    }
                    if (session != null && session.IsOpen)
                        session.Dispose();
                    CurrentSessionContext.Bind(iSessionFactory.OpenSession());
                    session = iSessionFactory.OpenSession();
                }
            }
        }

        public static ISession OpenSession
        {
            get
            {
                if (session == null || !session.IsOpen)
                {
                    session = null;
                    buildSessionFactory();
                }
                return session;
            }
        }
    }
  public class TransactionScopeHelper : SessionFactory, iTransactionScopeHelper
    {
        public static int count = 0;
        public TransactionScope getTransactionScope()
        {
            if (count == 0)
            {
                if (session != null)
                    session.Clear();
            }
            count++;
            return new TransactionScope(TransactionScopeOption.Required);
        }

        public void complete(TransactionScope tx)
        {
            count--;
            if (count == 0)
            {
                session.Flush();
                session = null;
            }
            tx.Complete();
        }

        public void rollbackTransaction()
        {
            count = 0;
            session = null;
        }
    }
 public T getById(long id)
 {
  ISession session = SessionFactory.OpenSession;
  return session.Get<T>(id);
 }
public T getById(长id)
{
ISession session=SessionFactory.OpenSession;
返回会话.Get(id);
}
每当我更新某个实体时,在几次刷新后会显示旧数据,在一些刷新后会再次检索新数据。这几乎是连续的。为什么我会遇到这个问题?任何帮助都将不胜感激。

这里发生了太多“不寻常”的事情,我几乎不知道从哪里开始

SessionFactory

NHibernate的会话工厂通常在应用程序启动时(或在第一次需要时)初始化一次,然后该实例将在程序期间有效,并在所有线程之间共享。我们通常不希望每个线程都有一个单独的实例(就像ThreadStatic那样)。反复初始化它将是一个严重的性能损失

如果存在会话,buildSessionFactory()将处理该会话,但除非会话为null,否则它将无法访问该代码,因此我不理解这里的真正意图

在buildSessionFactory()的末尾,iSessionFactory.OpenSession()被调用两次!一次就够了

您正在配置文件中设置当前会话上下文类,并调用CurrentSessionContext.Bind()。因此,您不需要维护自己的线程静态会话变量。这就是CurrentSessionContext的用途

最终必须处理会话。因此,调用名为like
OpenSession
的方法意味着我们将获得一个负责关闭的新会话。但是您自己的OpenSession()可以多次返回同一个会话,因此很难理解到底是谁负责关闭它。最好将其命名为
CurrentSession
或类似名称

TransactionScopeHelper

这也是不可能理解的。存在对变量
会话的引用,但未显示此变量的定义和设置。代码不完整。在某些情况下,会话引用被设置为null,但没有尝试对其进行处理,这是必需的

在会话上调用Clear()将从会话中删除所有状态,并使NHibernate无法跟踪所有加载的对象,因此无法执行脏检查并自动持久化。其他代码需要记住小心地重新添加所有内容

代码不显示实际创建会话、事务和事务范围的方式和时间。无法判断交互是否正确。会话是否知道事务范围

最后,回答你的问题:“为什么我会遇到这个问题?”

很抱歉,整个情况看起来一团糟。混乱的代码等于混乱的结果。当然,除非我上面提到的问题是由于部分拷贝粘贴遗漏了重要部分造成的。

这里有太多“不寻常”的东西,我几乎不知道从哪里开始

SessionFactory

NHibernate的会话工厂通常在应用程序启动时(或在第一次需要时)初始化一次,然后该实例将在程序期间有效,并在所有线程之间共享。我们通常不希望每个线程都有一个单独的实例(就像ThreadStatic那样)。反复初始化它将是一个严重的性能损失

如果存在会话,buildSessionFactory()将处理该会话,但除非会话为null,否则它将无法访问该代码,因此我不理解这里的真正意图

在buildSessionFactory()的末尾,iSessionFactory.OpenSession()被调用两次!一次就够了

您正在配置文件中设置当前会话上下文类,并调用CurrentSessionContext.Bind()。因此,您不需要维护自己的线程静态会话变量。这就是CurrentSessionContext的用途

最终必须处理会话。因此,调用名为like
OpenSession
的方法意味着我们将获得一个负责关闭的新会话。但是您自己的OpenSession()可以多次返回同一个会话,因此很难理解到底是谁负责关闭它。最好将其命名为
CurrentSession
或类似名称

TransactionScopeHelper

这也是不可能理解的。存在对变量
会话的引用,但未显示此变量的定义和设置。代码不完整。在某些情况下,会话引用被设置为null,但没有尝试对其进行处理,这是必需的

在会话上调用Clear()将从会话中删除所有状态,并使NHibernate无法跟踪所有加载的对象,因此无法执行脏检查并自动持久化。其他代码需要记住小心地重新添加所有内容

代码不显示实际创建会话、事务和事务范围的方式和时间。无法判断交互是否正确。会话是否知道事务范围

最后,回答你的问题:“为什么我会遇到这个问题?”

很抱歉,整个情况看起来一团糟。混乱的代码等于混乱的结果。当然,除非我上面提到的问题是由于剩下的部分拷贝粘贴造成的