在连接之间共享事务

时间:2014-05-30 10:26:19

标签: c# multithreading sqlconnection sqltransaction

我有一个FileShare抓取工具(获取权限并将其放到某处以供稍后审核)。目前,它正在启动多个线程来抓取同一个文件夹(以加快进程)。

在C#中,每个SqlConnection对象都有自己的SqlTransaction,由SqlConnection.BeginTransaction()调用启动。

这是当前解决方案的伪代码:

  1. 获取文件夹列表
  2. 对于每个文件夹获取子文件夹列表
  3. 对于每个子文件夹,启动一个线程来收集文件共享
  4. 每个线程都会将收集的数据保存到数据库
  5. 在数据库上运行审核报告
  6. 当其中一个子文件夹线程失败时,会出现问题。我们最终会进行部分文件夹扫描,而且#34;无法轻易检测到#34;。主要原因是每个线程都在单独的连接上运行。

    我希望在同一个事务中提交每个文件夹而不是不完整的扫描(当前情况,当某些线程失败时)。没有实现交易概念,但我正在评估选项。

    根据this answer的注释,生产者/消费者队列将是一个选项,但不幸的是内存是一个限制(由于启动的线程数)。如果生产者/消费者空间被提交到磁盘以克服RAM限制,则执行时间将会增加(由于与内存I / O相比非常有限的磁盘I / O)。我想我的记忆/时间妥协了。还有其他建议吗?

1 个答案:

答案 0 :(得分:1)

使用过时的绑定事务功能,可以在与SQL Server的多个连接上共享相同的事务。我从来没有使用它,我不会在它上面进行新的开发。这里似乎没必要。

难道你不能让所有生产者使用相同的连接和交易吗?锁上它。这显然会阻碍这个过程,但它可能仍然足够快。

您说您执行INSERT语句。对于批量插入,您可以使用速度非常快的SqlBulkCopy类。批量处理行,只有当>> 1000行缓冲时才执行批量插入。

我甚至不认为这里需要生产者/消费者。通过将生产与消费一起流水线化确实有利于性能,但它也引入了更复杂的线程。如果你想走这条路,你应该给IEnumerable<SqlDataRecord>SqlBulkCopy直接流式传输所有已生成的行而不进行中间缓冲。