假设有一个表A,记录有点多,我每次取1000条,对其进行foreach处理, 将处理之后的结果用事务写入3个表 B,C,D,
1000条处理完,再去取1000,如此循环。。。。。
怎么用多线程加速,单线程太慢了,我用的是用线程池数据访问用的Ado.net entity framework 。。。。。 但是有问题
具体看这里: link
给点代码 伪的也行啊 不好控制啊 可以自己像一个场景: 比如 表A10万条记录,2个字段,第一个字段guid,第二个都是0 ,
每次取1K条
弄10个线程
去处理它,把0改为1 存入 表B,表C,表D
(存的这三个步骤用事物,要么三个表都存进去,要么都不存) 表A可能一直在增长,怎么控制
假设这个场景:
比如表A (Uid guid primary key,status int) 有10000条status都为0,每次取1000条,对这1000条进行处理(假设简单点,每处理一条,就往C,D,E 表 插入一些数据,用事务保证3各表都插入成功了就可以,不管什么数据都可以,事务完成,更改表A中该记录status值为1) 用Ado.net entity framework 和事务怎么完成?
谢谢
可以参考我问的这个问题:http://stackoverflow.com/questions/6545266/how-can-i-use-multithreading-to-handle-a-list-in-c
对记录绑定一个状态标识,例如 completed = 1 每个线程都是 同一个方法。方法里就取 completed = 0 完成此记录后就更新为 completed = 1 。这样就不会冲突而且达到了加速处理了。
建立N个线程,每个线程1000条,进行处理(处理过程不包括写入),处理完后保存结果到公共内存或磁盘,等全部线程处理完后,把结果依次写入!
有一点需要注意, 在你的情境中,数据库的处理是主要部分,所以首先,我觉得你的问题应该是用存储过程来解决,而不是用这种循环来解决。
退一万步讲,如果你的命题实在很特殊,非要用c#来解决,那么应该建立一个总的调度线程,负责向工作线程分配行号(或其它主键),工作线程得到行号范围,就从数据库把它们取出来,然后进行其它工作,完成一轮后,向调度线程请求下一个行号范围。至于事务就不用说了,所有线程共享一个事务变量即可,非常简单,没什么可说的。
用多线程的话 我建议一个线程取不同的记录行数。比如:第1个线程去前1000条,第2线程去1000到2000条记录……。村数据也如此
处理采用多线程,写入数据库采用单线程.
可以考虑下并行编程,Parallel.For
1. 取1000条,放入队列中。
2. 用几个线程去将队列中的数据取出来插入表A,B,C。
3. 循环1 2步骤直到数据都导入完毕。
说几点,仅供参考。
1.估计你的处理最耗时的部分应该是根据表A中的数据生成3个表的数据的阶段(单纯逻辑处理,不包括从DB中取出和存储),所以在取数据的阶段没必要分成多任务来处理,除非你的数据量特别大(百万级以上),否则一次把数据取出来应该不比分成多任务处理慢。而这样做的好处是可以减少很多正确分割多数据段得麻烦。(除非你的表里有明确的可以唯一标识每一行并且能够起到等比例分割的字段,否则会有很多麻烦,即使使用row_number()函数)
2.对一次取回的数据再进行按任务分割这个容易多了。分别进行逻辑运算(不包括向DB更新)。对于多线程的控制,.net还是提供了很丰富的接口的。
3.等2中所有线程的处理都完成了,在进行数据更新。注意一定要用批处理的方式进行更新,否则一条一条更新的话即使单线程1000条的话也得10分钟左右。批处理可以使用SqlDataAdapter来做。
4.所有的操作过程中要根据业务的需求设置好合适的事物的隔离级别。否则保证不了数据更新的正确性和完整性。