在连接之间共享事务
本文关键字:事务 共享 之间 连接 | 更新日期: 2023-09-27 18:05:49
我有一个FileShare爬虫(获取权限并将它们放到某个地方以供以后审计)。目前,它正在启动多个线程来抓取同一个文件夹(以加快进程)。
在c#中,每个SqlConnection
对象都有自己的SqlTransaction
,由SqlConnection.BeginTransaction()
调用发起。
下面是当前解决方案的伪代码:
- 获取文件夹列表
- 为每个文件夹获取子文件夹列表
- 为每个子文件夹启动一个线程来收集文件共享
- 每个线程将收集到的数据保存到数据库
- 运行数据库审计报告
当其中一个子文件夹线程失败时出现问题。我们以部分文件夹扫描告终,这"不容易被检测到"。主要原因是每个线程运行在一个单独的连接上。
我希望在同一事务中提交每个文件夹,而不是不完全扫描(当前情况,当某些线程失败时)。没有实现任何事务概念,但我正在评估选项。
根据这个回答的注释,生产者/消费者队列将是一个选项,但不幸的是内存是有限的(由于启动线程的数量)。如果生产者/消费者空间被提交给磁盘以克服RAM限制,则执行时间将增加(由于与内存I/O相比,磁盘I/O非常有限)。我想我被记忆和时间的妥协所困住了。还有其他建议吗?
使用过时的绑定事务特性可以在SQL Server的多个连接上共享相同的事务。我从来没有使用过它,我也不会在它的基础上进行新的开发。这里似乎也没有必要。
你不能让所有的生产者使用相同的连接和事务吗?把它锁起来。这显然是进程的瓶颈,但它可能仍然足够快。
你说你执行INSERT
语句。对于批量插入,您可以使用SqlBulkCopy
类,这要快得多。批处理行,只有当你有>>1000行缓冲时才执行大容量插入。
我甚至不认为这里需要生产者/消费者。通过将生产与消费流水线化,确实可以提高性能,但它也引入了更复杂的线程。如果你想走这条路,你可能应该给SqlBulkCopy
类一个IEnumerable<SqlDataRecord>
,直接流所有已经产生的行到它没有中间缓冲。