在事务中同时运行任务时集成测试错误

问题描述 投票:0回答:1

我编写了一个集成测试,用两个线程同时插入两个文档,测试完成后,我希望测试期间插入的记录都不存在于数据库中。

我在集成测试中使用了这个技巧(在测试完成时回滚所有测试事务)。我想在集成测试的操作部分同时运行两个任务,所以我编写了以下测试(我从此链接得到了这个想法):

[TestClass] public class MyIntegrationTest : IntegrationTestsBase { [TestMethod] public void SaveTwoDocumentsSimultaneously_WorkSuccessfully() { //Assign var doc1 = new Document() {Number = "Test1"}; var doc2 = new Document() {Number = "Test2"}; //action CountdownEvent countdown = new CountdownEvent(2); ThreadPool.QueueUserWorkItem(WorkerThread, new object[] { Transaction.Current.DependentClone(DependentCloneOption.BlockCommitUntilComplete), doc1, countdown }); ThreadPool.QueueUserWorkItem(WorkerThread, new object[] { Transaction.Current.DependentClone(DependentCloneOption.BlockCommitUntilComplete), doc2, countdown }); countdown.Wait(); //assert //assertion code for chack two document inserted .... } }
这是我的集成基类(通过 

TransactionScope

 包装每个测试并在测试运行结束时回滚它):

[TestClass] public abstract class IntegrationTestsBase { private TransactionScope _scope; [TestInitialize] public void Setup() { this._scope = new TransactionScope(TransactionScopeOption.Required, new System.TimeSpan(0, 10, 0)); } [TestCleanup] public void Cleanup() { this._scope.Dispose(); } }
这是

WorkerThread

代码(我从
此链接获得):

private static void WorkerThread(object state) { if (state is object[] array) { var transaction = array[0]; var document = array[1] as Document; CountdownEvent countdown = array[2] as CountdownEvent; try { //Create a DependentTransaction from the object passed to the WorkerThread DependentTransaction dTx = (DependentTransaction)transaction; //Sleep for 1 second to force the worker thread to delay Thread.Sleep(1000); //Pass the DependentTransaction to the scope, so that work done in the scope becomes part of the transaction passed to the worker thread using (TransactionScope ts = new TransactionScope(dTx)) { //Perform transactional work here. using (var ctx = new PlanningDbContext()) { ctx.Documents.Add(doc); ctx.SaveChanges(); //<----exception occures here when second document insert } //Call complete on the transaction scope ts.Complete(); } //Call complete on the dependent transaction dTx.Complete(); } catch (Exception ex) { Debug.WriteLine(ex); } finally { countdown?.Signal(); } } }
当我运行测试时,我在保存文档点时收到以下错误:

System.Data.Entity.Infrastruct.DbUpdateException:更新条目时发生错误。有关详细信息,请参阅内部异常。 ---> System.Data.Entity.Core.UpdateException:更新条目时发生错误。有关详细信息,请参阅内部异常。 ---> System.Transactions.TransactionException:该操作对于事务的状态无效。

我的代码中的哪个位置导致了此错误,我该如何解决该错误?

c# multithreading entity-framework integration-testing transactionscope
1个回答
0
投票
测试工作完美。

在测试中,您完成事务,然后在清理中,您处置事务范围。完成事务会将其中发生的情况保存到数据库中,并且处理事务会释放用于处理事务的已分配资源。

解决问题的一个更简单的解决方案可能是在测试之前备份数据库,然后在测试后恢复它。

© www.soinside.com 2019 - 2024. All rights reserved.