C# 如何使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是一个非线程安全对象,表示数据库

我有一个NHibernate存储库类,它在一个事务中对多个表执行一些读取操作

但是我有一段旧代码,它试图在并行线程上调用这个NHibernate类,比如

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,并在多个线程中处理。不要从后台线程访问实体
这段代码的多线程化是否重要?若有,原因为何?是因为性能(这是我们可以用另一种方法解决的问题)还是改变它所需的工作量(无法那么容易解决的问题)?应用程序类型也有一定的重要性。如果它是一个web站点,那么在HTTP请求处理中添加并行性对于应用程序的可伸缩性来说是一个糟糕的选择,应该不惜一切代价避免。这段代码是多线程的重要吗?若有,原因为何?是因为性能(这是我们可以用另一种方法解决的问题)还是改变它所需的工作量(无法那么容易解决的问题)?应用程序类型也有一定的重要性。如果它是一个web站点,那么在HTTP请求处理中添加并行性对于应用程序的可伸缩性来说是一个糟糕的选择,应该不惜一切代价避免。