C# 在连接之间共享事务
我有一个文件共享爬虫程序(获取权限并将其放在某个地方供以后审核)。目前,它正在启动多个线程对同一文件夹进行爬网(以加快进程) 在C#中,每个C# 在连接之间共享事务,c#,multithreading,sqlconnection,sqltransaction,C#,Multithreading,Sqlconnection,Sqltransaction,我有一个文件共享爬虫程序(获取权限并将其放在某个地方供以后审核)。目前,它正在启动多个线程对同一文件夹进行爬网(以加快进程) 在C#中,每个SqlConnection对象都有自己的SqlTransaction,由SqlConnection.BeginTransaction()调用启动 以下是当前解决方案的伪代码: 获取文件夹列表 对于每个文件夹,获取子文件夹列表 对于每个子文件夹,启动一个线程以收集文件共享 每个线程都将收集的数据保存到数据库中 在数据库上运行审核报告 当其中一个子文件夹线程出现
SqlConnection
对象都有自己的SqlTransaction
,由SqlConnection.BeginTransaction()
调用启动
以下是当前解决方案的伪代码:
根据的注释,生产者/消费者队列将是一个选项,但遗憾的是内存是一个限制(由于已启动线程的数量)。如果生产者/消费者空间用于磁盘以克服RAM限制,则执行时间将增加(因为与内存I/O相比,磁盘I/O非常有限)。我想我被困在了记忆/时间的折衷中。还有其他建议吗?可以使用过时的绑定事务功能在与SQL Server的多个连接上共享同一事务。我从未使用过它,也不会在它的基础上进行新的开发。这里似乎也没有必要 难道你不能让所有的生产者使用相同的连接和事务吗?把它锁上。这显然阻碍了这一过程,但它可能仍然足够快 您说您执行
INSERT
语句。对于批量插入,您可以使用速度非常快的SqlBulkCopy
类。对行进行批处理,并仅在缓冲了>>1000行时执行批量插入
我甚至不认为这里需要生产者/消费者。通过将生产与消耗进行流水线连接,它确实会提高性能,但它也会引入更复杂的线程。如果你想走这条路,你可能应该给
SqlBulkCopy
类一个IEnumerable
,直接将生成的所有行流式传输到其中,而不需要中间缓冲。如果你没有足够的内存在一个事务中保存你想要的所有内容,你的要求就不太清楚了,我怀疑是否会有解决办法。还不清楚您所说的“以防生产者/消费者空间被提交到磁盘”是什么意思。如果您考虑到这些因素,我认为您的事务也会运行很长时间,因此可能会将数据/资源锁定太长时间,从而导致问题。“我想你需要一个完全不同的方法。”JonSkeet请看一下编辑过的问题。我希望这是清楚的now@AllanS.Hansen我知道潜在的锁定问题。在将数据移动到报告表之前,我使用临时表收集数据。并发插入不应产生问题。我愿意接受建议如果您将(自定义)事务包装到并发插入上,则并发插入将导致问题。如果您没有掌握事务逻辑,那么您甚至可能会使自己陷入僵局。但是很多关于解决方案的事情取决于你所处的环境和其中的因素;但是,如果你有一个内存限制启动许多线程,我会考虑开始更少的线程开始,然后收集应用层中的数据,以便更少的更新/插入到数据库中,从而缩短事务。