事务范围和数据上下文

发布于 2024-10-04 17:47:42 字数 1095 浏览 3 评论 0原文

我意识到这个问题以前就有人问过,但我还没有找到真正有效的答案。

当我的单元测试尝试调用使用 Linq 查询数据库的 Web 服务时,出现了我的问题。

单元测试的设置如下:

[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();
}

service.GetItems 方法如下所示:

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 null;
}

当 Linq 查询尝试执行时,会引发以下异常:

该操作对于事务状态无效。

我相信这与嵌套事务有关,但我需要保持测试类中的事务打开,以便测试数据实际上不会保存到数据库中,并且在测试运行后我可以处理它。

另外,我的托管位于共享实例上,因此我无法直接对服务器进行任何更改。

有没有办法让它按原样工作,或者在这种情况下是否有使用 TransactionScope 的替代方法?

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 null;
}

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?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

遇见了你 2024-10-11 17:47:42

您正尝试在单个 TransactionScope 内创建到同一数据库的两个连接 - 一个连接用于测试进程,另一个连接用于 Web 服务进程。这是行不通的,因为在数据库中,来自不同进程的事务显然不能嵌套。

您应该在此处更改测试方法。阅读简的回答。

作为解决方法,您可以让您的 Web 服务管理事务。一个方法,比如 BeginGlobalTran 应该为 Web 服务创建一个全局 Transaction(或 TransactionScope)对象(存储在属性中),它的所有其他方法都应该使用这个对象(因此,所有其他事务都嵌套在“全局”事务),另一种方法是,RollbackGlobalTran 应该回滚这个“全局”事务。
话虽这么说,这是一种解决方法,可能会导致一些意外的副作用(例如,该方法中的错误将使“全局”事务无法提交,因此您必须重新启动它以避免进一步的错误)。

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).

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文