我正在编写一个多线程服务,用于处理状态为1(未处理)的进程。一旦它们被拾取,我需要将这些行的状态更改为2(表示正在进行中),以便另一个线程(在几秒钟内生成)不会拾取这些行进行处理。
对于选择,我会做这样的事情:
var jobs = from j in db.Jobs
where j.Status == 1
select j;
如何重写此行以更新行并同时选择它们?
答案 0 :(得分:1)
使用transaction。有一些例子说明它是如何运作的here。
答案 1 :(得分:1)
这是典型的队列模式,要正确有效地执行此操作,必须使用带输出的更新:
UPDATE TOP (...) table
SET status = 2
OUTPUT deleted.*
WHERE status = 1;
没有等效的Linq2Sql,对于这个特定的工作,你不应该使用Linq。只需创建一个存储过程并将其显式添加到数据上下文中,然后将返回的类型修改为Jobs。你不会使用事务,而不是任何其他结构,甚至接近使用带有OUTPUT的UPDATE的性能。
我还添加了一个TOP子句,这在队列模式中相当常见,每个读者只需要有限的工作量就可以承受负载峰值。
答案 2 :(得分:0)
由于许多线程可能互相踩踏,最简单的方法是设置为当前作业或线程ID的另一个字段:
update t set runner_id = ? where runner_id = 0
select * from t where runner_id = ?
(? = my thread or connection id)
或者您可以使用锁或事务锁定表并执行2次查询:选择,然后更新到处理
答案 3 :(得分:0)
选择后我会有一个foreach更新值,然后提交它们,然后继续执行程序的其余部分
foreach (Job j in jobs)
{
j.Status = 0;
}
db.SubmitChanges()
然后你仍然有你的工作,数据库更新......