我有一个多线程事务和实体框架的问题。我有一个线程,它在事务中运行,我想在同一个事务中有更多的工作线程工作。下面的代码说明了情况(在EF上下文中有一个虚拟实体,代码基本上产生了5个线程,我想在每个线程中插入一些实体,并在主线程的末尾,我想继续使用DB,但是以保持整个过程隔离在一个交易):多线程事务异常终止与实体框架
using(var scope = new TransactionScope())
{
int cnt = 5;
ManualResetEvent[] evt = new ManualResetEvent[cnt];
for(int i = 0; i < cnt; i++)
{
var sink = new ManualResetEvent(false);
evt[i] = sink;
var tr = Transaction.Current.DependentClone(
DependentCloneOption.BlockCommitUntilComplete);
Action run =() =>
{
using (var scope2 = new TransactionScope(tr))
{
using (var mc = new ModelContainer())
{
mc.EntitySet.Add(new Entity()
{
MyProp = "test"
});
mc.SaveChanges();
}
}
sink.Set();
};
ThreadPool.QueueUserWorkItem(r => run());
}
ManualResetEvent.WaitAll(evt);
using (var mc = new ModelContainer())
{
Console.WriteLine(mc.EntitySet.Count());
}
Console.ReadKey();
}
问题是,该异常引发mc.SaveChanges();.内部异常是TransactionException:“该操作对于事务状态无效。”似乎在某个时候,交易被中止。我认为这是第一次线程调用SaveChanges()后,但林不知道。任何想法为什么交易中止?
但我不明白的是,如果我没有事务执行该代码,它的工作原理。我正在为每个线程创建新的数据库上下文,并且我相信DependentTransaction应该用于跨线程共享事务 - [link](http://msdn.microsoft.com/zh-CN/LIbrary/system.transactions .dependenttransaction(v = vs.110)) –
在仔细检查你的代码后,我看到你在做什么。这确实可行,但我仍然认为这是开发系统的一种可怕方式。你试图解决什么问题? – Steven
这不是我的生产代码的工作方式。我的目标是做一些单元集成测试。我正在测试针对MSSQL服务器的业务逻辑层。在测试init方法中,我开始一个事务,然后运行测试代码,然后检查数据库内容。测试完成后,我将回滚事务以保持数据库处于原始状态。这种方法完美适用于单线程操作。但是当操作使用多于一个线程时,我需要在这些线程中共享事务。最好不需要更改生产代码。 –