4

是否可以打開TransactionScope,運行異步操作的異步Task s,在EF4 ObjectContext上運行,然後提交結果?EF4,TransactionScope和任務<>

如何在EF4中推斷當前事務範圍?如果/當某個任務在與事務處理作用域不同的線程上被調度時,這會失敗嗎?

回答

4

是的。對於初學者來說,實體框架只是使用下面的一個提供者(默認情況下是System.Data.SqlClient),它將從正在執行的線程中提取「環境」事務上下文。所以,從那裏,唯一的訣竅就是將單筆交易傳播到你旋轉起來的Tasks。我已經解釋瞭如何在this post這裏做到這一點。

雖然這篇文章更多的是關於PLINQ衍生任務的提議,但如果您手動啓動自己的Tasks,則同樣的方法也適用。如果你想要一個代碼示例,請告訴我你的Task產卵如何工作的基本細節,以便我可以給出很好的示例代碼。

0

不,你不能(有用)這樣做。

儘管Drew Marsh的回答是正確的(即存在使交易跨越線程邊界的方法),但它不會幫助您。 ObjectContext不是線程安全的 - 你不應該從其他線程訪問它,你應該肯定不會在其他線程上更新它;您將會遇到未定義的行爲:您可能會遇到數據損壞,如果您幸運的話會導致崩潰。

如果你想要多線程ObjectContext訪問,你需要手動序列化訪問,例如使用鎖。但是,如果你這樣做,你可能只需從一個線程訪問上下文;它通常更簡單,幾乎總是更快 - 然後您的交易就沒有問題。

如果您堅持要手動同步對ObjectContext的訪問權限,而不是使用線程,則還可以使用普通的CommittableTransaction,並按明示方式傳遞該請求,而不是使用環境事務;因爲無論如何你都需要手動控制事務,所以用對象的顯式處理而不是棘手的狀態轉換(其中哪些線程的確切細節在代碼中至關重要但不明確)來做到這一點更爲明確。順便說一句,如果你使用環境事務,我會小心任務調度,尤其是使用C#5的異步功能,因爲你可能需要清楚地知道執行何時可以改變線程(我已經從來沒有嘗試過,所以我不能給你任何指針,不幸的是)。

摘要:只是不這樣做:你通過多線程由於ObjectContext(並在實踐中,DB)的限制越來越併發,所以你還不如在一個線程中留下一個事務,並保持它很簡單。未來的維護者會爲了清晰起見而感謝你。

相關問題