4

是否可以打开 a ,运行在 EF4 上TransactionScope运行的 async 负载,然后提交结果?TaskObjectContext

EF4 中如何推断当前事务范围?如果/当任务被安排在与事务范围不同的线程上时,这会失败吗?

4

2 回答 2

4

是的。对于初学者,Entity Framework 只使用下面的提供程序(默认为 System.Data.SqlClient),它将从正在执行的线程中获取“环境”事务上下文。因此,从那里开始,唯一的技巧就是将单个交易传播给Tasks您启动。我已经在这篇文章中解释了如何做到这一点。

虽然那篇文章更多地是关于传播到 PLINQ 衍生任务,但如果您手动启动自己的Tasks. 如果你想要一个代码示例,请给我关于你的生成Task将如何工作的基本细节,这样我就可以给出很好的示例代码。

于 2011-12-10T17:49:08.870 回答
0

不,你不能(有用地)这样做。

尽管 Drew Marsh 的回答是正确的(存在使事务跨线程边界的方法),但这对您没有帮助。 ObjectContext不是线程安全的——你不应该从其他线程访问它,你绝对不应该在其他线程上更新它;你会有未定义的行为:你可能会遇到数据损坏,这(如果你幸运的话)会导致崩溃。

如果您想要多线程ObjectContext访问,则需要手动序列化访问,例如使用锁。但如果你这样做,你还不如简单地从一个线程访问上下文;它通常更简单,而且几乎总是更快 - 然后你的交易就不会有问题了。

如果你坚持手动同步访问ObjectContext而不是使用线程,你也可以使用一个普通CommittableTransaction的并显式地传递它而不是使用环境事务;由于无论如何您都需要手动控制事务,因此使用对象的显式句柄而不是棘手的状态转换(其中哪个线程运行的确切细节在代码中至关重要但不明确)更清楚。

顺便说一句,如果您确实使用环境事务,我会小心任务调度,尤其是使用 C# 5 的异步功能,因为您可能需要清楚地知道执行何时可以更改线程(我从未尝试过,所以很遗憾,我不能给你任何指示)。

摘要:只是不要这样做:由于ObjectContext(实际上是数据库)的限制,您不会通过多线程获得并发性,因此您不妨将一个事务留在一个线程上并保持简单。未来的维护者将感谢您的清晰说明。

于 2013-01-28T00:06:36.137 回答