是否可以打开 a ,运行在 EF4 上TransactionScope
运行的 async 负载,然后提交结果?Task
ObjectContext
EF4 中如何推断当前事务范围?如果/当任务被安排在与事务范围不同的线程上时,这会失败吗?
是否可以打开 a ,运行在 EF4 上TransactionScope
运行的 async 负载,然后提交结果?Task
ObjectContext
EF4 中如何推断当前事务范围?如果/当任务被安排在与事务范围不同的线程上时,这会失败吗?
是的。对于初学者,Entity Framework 只使用下面的提供程序(默认为 System.Data.SqlClient),它将从正在执行的线程中获取“环境”事务上下文。因此,从那里开始,唯一的技巧就是将单个交易传播给Tasks
您启动。我已经在这篇文章中解释了如何做到这一点。
虽然那篇文章更多地是关于传播到 PLINQ 衍生任务,但如果您手动启动自己的Tasks
. 如果你想要一个代码示例,请给我关于你的生成Task
将如何工作的基本细节,这样我就可以给出很好的示例代码。
不,你不能(有用地)这样做。
尽管 Drew Marsh 的回答是正确的(存在使事务跨线程边界的方法),但这对您没有帮助。 ObjectContext
不是线程安全的——你不应该从其他线程访问它,你绝对不应该在其他线程上更新它;你会有未定义的行为:你可能会遇到数据损坏,这(如果你幸运的话)会导致崩溃。
如果您想要多线程ObjectContext
访问,则需要手动序列化访问,例如使用锁。但如果你这样做,你还不如简单地从一个线程访问上下文;它通常更简单,而且几乎总是更快 - 然后你的交易就不会有问题了。
如果你坚持手动同步访问ObjectContext
而不是使用线程,你也可以使用一个普通CommittableTransaction
的并显式地传递它而不是使用环境事务;由于无论如何您都需要手动控制事务,因此使用对象的显式句柄而不是棘手的状态转换(其中哪个线程运行的确切细节在代码中至关重要但不明确)更清楚。
顺便说一句,如果您确实使用环境事务,我会小心任务调度,尤其是使用 C# 5 的异步功能,因为您可能需要清楚地知道执行何时可以更改线程(我从未尝试过,所以很遗憾,我不能给你任何指示)。
摘要:只是不要这样做:由于ObjectContext
(实际上是数据库)的限制,您不会通过多线程获得并发性,因此您不妨将一个事务留在一个线程上并保持简单。未来的维护者将感谢您的清晰说明。