为什么该TransactionScope在第一个请求完成之前不阻止后续请求?

用户名

我已经研究了两天的交易,也许在吸收了如此多的信息之后,我似乎遗漏了一些明显的东西。这里的目标是阻止同时请求。如果condition为true,则插入数据,之后condition将为false。同时请求都condition将在插入数据之前进行检查,然后都将尝试插入数据。

public async Task<ActionResult> Foo(Guid ID)
{
    Debug.WriteLine("entering transaction scope");

    using (var transaction = new TransactionScope(
        TransactionScopeOption.Required,
        new TransactionOptions() { IsolationLevel = IsolationLevel.Serializable },
        TransactionScopeAsyncFlowOption.Enabled
        ))
    {
        Debug.WriteLine("entered transaction scope");

        var context = new DbContext();

        Debug.WriteLine("querying");
        var foo = context.Foos.FirstOrDefault(/* condition */);
        Debug.WriteLine("done querying");

        context.Foos.Add(new Foo());

        /* async work here */

        Debug.WriteLine("saving");
        context.SaveChanges();
        Debug.WriteLine("saved");
        Debug.WriteLine("exiting transaction scope");
        transaction.Complete();
        Debug.WriteLine("exited transaction scope");

        return View();
    }
}

这是使用Fiddler一次执行两个请求时的调试输出:

进入交易范围
输入交易范围
查询
完成查询
进入交易范围
输入交易范围
查询
完成查询
保存
保存
已保存
System.Data.dll中发生类型为'System.Data.SqlClient.SqlException'的第一次机会异常
退出交易范围
退出交易范围

这是我对代码应该如何工作的理解:

所以很明显,它没有像我想要的那样工作。有可能实现我的目标TransactionScope吗?还是我必须升级到EF 6?

雷木斯·鲁萨努(Remus Rusanu)

序列化无法解决旧的“先插入后检查”的问题。两个可序列化的事务可以同时评估条件,得出必须插入的结论,然后两者都尝试仅插入一个失败和一个成功。这是因为所有读取在可序列化隔离下彼此兼容(实际上,它们在所有隔离级别下均兼容)。

如何解决这个问题有很多流派。一些建议使用MERGE有人建议在检查查询中使用锁定提示来获取X或U锁定。我个人建议始终插入并优雅地恢复重复的键冲突。是另一种方法的工作是使用显式应用程序锁

EF或System.Transactions确实只会增加疑问。从根本上讲,这是一个后端SQL问题。至于如何在线程之间流动事务作用域的问题,请参阅Get TransactionScope以与async / await一起使用(显然,从阅读OP中您已经知道了这一点……我没有在第一次阅读中进行注册)。您将需要此代码来使您的异步代码在适当的上下文中使用,但是阻止/锁定仍然是基本的后端问题。

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

如何仅在第一个API请求完成后才发出后续API请求?

laravel_token 对第一个请求有效,但对后续请求无效

在第一个请求完成后发送第二个请求

Django 在返回第一个请求之前执行第二个请求

为什么阿波罗无法在第一个请求中获取数据?

为什么只有我的第一个HTTP请求运行?

为什么Spring Rest服务在第一个请求上速度较慢?

为什么第一个Rails请求的测试速度非常慢?

为什么Fetch API将第一个PUT请求发送为OPTIONS

为什么我收到第一个请求的OVER_QUERY_LIMIT答复?

为什么从请求中获取第一个参数是错误的?

让多个请求等待第一个请求完成(缓存)

在循环中使用Jsoup connect()。第一个请求总是比其他所有后续请求慢

为什么第一个交替不匹配?

为什么不附加第一个元素

为什么第一个网络通话比后续的通话花费更多的时间?

为什么第一个sbrk的返回值与后续调用不同?

有第二个okHTTP请求,等待第一个完成Android

如果在我收到第一个请求的响应之前发出了第二个HTTP请求,会发生什么情况?

HttpClient.BaseAddress的用途是什么,为什么在第一个请求后不能更改它

为什么当std:list <int> :: iterator的std :: distance()在最后一个在第一个之前之前不返回负数?

Ajax请求等待,直到第一个AJAX调用未完成

为什么POST请求在第一个数据包中使用PSH标志?

为什么在MVC应用程序的第一个请求中发生路由表填充

为什么通过 XMLHttp 请求只从 html 字符串中出现第一个元素?

为什么从 nodejs 服务器重定向仅适用于第一个请求?

为什么第二个装饰工在完成第一个装饰工之前没有完成工作?

同时有多个php请求,直到第一个请求完成,第二个请求才完成

为什么第一个类型不针对我的第一个脚注?