【问题标题】:C# Reading database after SaveChangesAsyncC# SaveChangesAsync 后读取数据库
【发布时间】:2015-09-22 02:24:56
【问题描述】:

如果我对 (ms)SQL 数据库进行写入并使用 SaveChangesAsync() 保存更改,是否有可能在未来读取数据库时读取未保存的更改?

因素可能包括,是否使用不同的 DbContext、线程或进程来访问数据库。

【问题讨论】:

  • 使用await 等待异步操作完成,然后再读回结果。
  • 使用事务确保 ACID。

标签: c# .net sql-server entity-framework asynchronous


【解决方案1】:

简答,否(Tim P 被错误告知)。

调用DbContext.SaveChangesAsync 将在保存期间自动创建一个Transaction

这意味着如果任何其他线程尝试访问该表,则可能会发生多种情况之一。

通常这意味着另一个数据库调用将在另一个线程上阻塞,而事务未提交/未回滚。

【讨论】:

  • 所以如果只使用SaveChangesSaveChangesAsync(即不设置自定义TransactionIsolationLevel),那么无论你使用什么样的多线程/进程, EF调用保证安全吗?使用ExecuteSqlCommand 会有所改变吗?
  • @Cardin 我不确定是否使用 ExecuteSqlCommand。但是,通常会在 ExecuteSqlCommand 上循环,这将是一个问题。
  • 另一个问题,如果表 A 具有使其依赖于表 B 的 FK 约束,如果表 B 仍在运行,Transaction 是否足够聪明,可以知道阻止对表 A 的写访问在其他地方居住?
  • 请阅读数据库事务。不清楚你在问什么,这听起来是一个很简单的问题,但在你开发必要的术语之前,我无法理解这个问题。到那时你应该有答案了。
【解决方案2】:

简短回答:是的。

这取决于几个因素,例如您要保存到数据库中的多少。如果您要保存 1,000 行/对象,并且它是一个缓慢的数据库服务器,则此时间窗口可能足够宽以至于另一个线程正在读取,而(例如)第 879 行尚未保存。这与异步无关。这是处理多用户关系数据库系统时的正常并发问题。

【讨论】:

  • 我明白了.... 我设法通过在接触同步代码的相同表的方法上加锁来避免并发问题。{}我认为我还不需要使我的写入异步(可能不是瓶颈),而是假设。谢谢!
  • @Cardin NOOOOOO 你不要在你的 DbContext 上使用lock。数据库有自己的并发模型,比 .net 更有效。
  • 上次我检查了DbContext.SaveChanges 自动将数据库调用包装在事务中。所以这应该是不可能的。
  • 如果您使用“await”阻塞调用线程,事务将有所帮助。但是,如果您使用 Async(没有等待)启动该过程,那么您确实会冒着在下一行代码执行之前它没有完成 SaveChanges() 的风险。
猜你喜欢
  • 2019-01-22
  • 1970-01-01
  • 2015-05-06
  • 2015-08-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多