开发者

TransactionScope and DataContext

开发者 https://www.devze.com 2023-01-27 06:23 出处:网络
I realise this question has been asking before, but I\'ve yet to find an answer that actually works. My issue is occuring when my unit tests are trying to call a web service that uses Linq to query t

I realise this question has been asking before, but I've yet to find an answer that actually works.

My issue is occuring when my unit tests are trying to call a web service that uses Linq to query the database.

The unit test is set up like so:

[TestInitialize]
public void SetUp()
{
    var scope = new TransactionScope(TransactionScopeOption.Required,TimeSpan.MaxValue);
    var database = new DatabaseDataContext();
}

[TestCleanup]
public void TearDown()
{
    scope.Dispose();
    database.Dispose();
}

[TestMethod]
public void GetCategoryList_Success()
{
    // create test data
    var result = service.GetItems();
}

The service.GetItems method looks like so:

try
{
    using (DatabaseDataContext database = new DatabaseDataContext())
    {
        var items = (from i in database.Items
                    select i).ToList<Items>();
        return items;
    }
}
catch (Exception ex)
{
   // log error
   return nu开发者_如何学运维ll;
}

When the Linq query tries to execute, the following exception is thrown:

The operation is not valid for the state of the transaction.

I believe this is to do with nested transactions, but I need to keep the transaction in the test class open so that the test data is not actually saved to the database and I can dispose of it once the test is run.

Also, my hosting is on a shared instance, so I am unable to make any changes to the server directly.

Is there a way to get this to work as is, or alternatively, is there an alternative to using TransactionScope in this context?


You are trying to create two connections to the same database within a single TransactionScope - one connection for the test process, and another one for the web service process. This doesn't work because in the database tranasctions from different processes obviously can't be nested.

You should change your approach to testing here. Read Jan's answer.

As a workaround, you could make your web service manage the transaction. A method, say, BeginGlobalTran should create a global Transaction (or TransactionScope) object for the web service (stored in property), all other its methods should use this object (so, all other transactions are nested within the 'global' transaction), another method say, RollbackGlobalTran should rollback this 'global' transaction.
That being said, it is a workaround and it might cause some unexpected side-effects (for instance, an error in the method will make the 'global' transaction uncommitable, so you will have to restart it to avoid further errors).

0

精彩评论

暂无评论...
验证码 换一张
取 消