C# 如何使NHibernate存储库线程安全
我有一个NHibernate存储库类,它在一个事务中对多个表执行一些读取操作 但是我有一段旧代码,它试图在并行线程上调用这个NHibernate类,比如C# 如何使NHibernate存储库线程安全,c#,multithreading,nhibernate,fluent-nhibernate,C#,Multithreading,Nhibernate,Fluent Nhibernate,我有一个NHibernate存储库类,它在一个事务中对多个表执行一些读取操作 但是我有一段旧代码,它试图在并行线程上调用这个NHibernate类,比如 someList.AsParallel().Select(x=>x.repo.GetData()); 操作失败,说明SQL不支持多个事务,如何使NHibernate中的ISession线程安全?NHibernateISession不是线程安全的,句号。 来自NHibernate参考文件: ISession是一个非线程安全对象,表示数据库
someList.AsParallel().Select(x=>x.repo.GetData());
操作失败,说明SQL不支持多个事务,如何使NHibernate中的ISession线程安全?NHibernate
ISession
不是线程安全的,句号。来自NHibernate参考文件:
ISession
是一个非线程安全对象,表示数据库的单个工作单元
你应该改变你的旧代码
不管怎么说,这段代码看起来像是一个编码恐惧。它遭受了n+1负载的坏习惯。这种情况通常发生在延迟加载未正确设置的情况下(忘记在实体和集合上设置足够的in映射,而没有设置default\u batch\u fetch\u size
configuration参数)。但在那里,它是显式编码的
在循环中调用DB是一种性能反模式,您应该首先修复它。在AsParallel
中调用它看起来只是原始开发人员“优化”这种编码恐惧的拙劣尝试
要修复它,您应该在一次调用中加载所有数据,然后根据需要将其发送到列表中。您可以首先将数据投影到字典中,以避免使用O(n²)调度算法
完成后,AsParallel
应该消失了,线程安全问题也会消失
如果事情太复杂(比您的示例显示的要复杂得多),或者确实对应于需要并行处理的事情,那么您应该为并行处理中的每个
GetData
实例化一个专用的ISession
。ISession
不是线程安全的,period.来自NHibernate参考文件:
ISession
是一个非线程安全对象,表示数据库的单个工作单元
你应该改变你的旧代码
不管怎么说,这段代码看起来像是一个编码恐惧。它遭受了n+1负载的坏习惯。这种情况通常发生在延迟加载未正确设置的情况下(忘记在实体和集合上设置足够的in映射,而没有设置default\u batch\u fetch\u size
configuration参数)。但在那里,它是显式编码的
在循环中调用DB是一种性能反模式,您应该首先修复它。在AsParallel
中调用它看起来只是原始开发人员“优化”这种编码恐惧的拙劣尝试
要修复它,您应该在一次调用中加载所有数据,然后根据需要将其发送到列表中。您可以首先将数据投影到字典中,以避免使用O(n²)调度算法
完成后,AsParallel
应该消失了,线程安全问题也会消失
如果事情太复杂(比您的示例显示的要复杂得多),或者确实对应于需要并行处理的事情,那么您应该为并行处理中的每个
GetData
实例化一个专用的ISession
。注意,当使用延迟加载和代理时,即使实体也不是线程安全的
- 如果要并行化查询,则需要在单独的事务中进行。考虑隔离和原子性。如果需要在单个事务中执行,则需要以不同的方式提高性能
- 如果要对实体进行并行计算,则应在主线程中执行优化查询,将实体中的数据复制到DTO,并在多个线程中处理。不要从后台线程访问实体李>
- 如果要并行化查询,则需要在单独的事务中进行。考虑隔离和原子性。如果需要在单个事务中执行,则需要以不同的方式提高性能
- 如果要对实体进行并行计算,则应在主线程中执行优化查询,将实体中的数据复制到DTO,并在多个线程中处理。不要从后台线程访问实体李>