场景:
需要将大量实体从集成数据库加载到生产数据库。我们使用NHibernate将内容加载到prod DB中,因为涉及的业务规则已经使用我们的持久化实体以C#编写。一切运行正常,我们将有效的实体加载到DB中。RDBMS是SQL Server 2005 (可以升级到2008)。
问题是:
要加载的实体数量将很快疯狂增长,我们非常确定它将花费比预期更长的时间,无法满足客户的要求。
解决方案(?):
简单地并行运行很容易:将所有实体拆分到存储桶中并并行导入它们。
问题是它们都插入到同一个表中,并且所有进程都会在表锁中遇到瓶颈。
所以问题是:有没有一种方法可以使这些插入操作不会被试图在同一个表中插入的其他事务锁定表?我听说过快照隔离级别,但没有发现有人真正使用它。任何指导都是值得感谢的。
发布于 2010-12-22 22:34:07
我认为10.4 Optimistic concurrency control这一章应该能帮助你把事情做好。您可以为这种类型的插入定义显式隔离级别。本文建议使用版本化,但如果您不需要使用版本化,因为您的数据只是插入,而没有更新,您可以跳过这一步。在这种情况下,最后一次提交获胜。
发布于 2010-12-22 22:20:20
是否可以插入到不同的表中(如上所述,每个“存储桶”一个),并将它们连接到一个视图中?客户看不出有什么不同,只是加载时间减少了80%……
发布于 2010-12-22 22:29:24
我没有任何使用NHibernate的经验,但是在.NET中,您可以使用SqlBulkCopy (或使用bulk INSERT / BCP)并行地批量加载数据。在正在加载的表上应用TABLOCK,这些批量操作将删除表上的批量更新锁,如果您有2个进程使用批量更新锁,它们将运行得很好。您需要装载到堆中(表上没有聚集索引)。
这是相反的,如果你有多个进程进行INSERT...SELECT,例如,这将获得排他的,表级锁,因此将相互阻塞。
我推荐this MSDN article -在那里有更多的细节和信息。希望这样的事情对你来说是可能的。
此外,如果可以,在加载之前从表中删除索引,然后在之后重新创建它们-这将提高加载速度。
https://stackoverflow.com/questions/4510003
复制相似问题