【问题标题】:LINQ to SQL and Concurrency IssuesLINQ to SQL 和并发问题
【发布时间】:2010-09-16 11:33:24
【问题描述】:

我们正在尝试建立一个大批量订单记录系统。 有三个主表: 1. 订单 2. 订单详情 3. 订单发货

Shipment 表包含每个订单的 n 条记录,并且在客户接受订单之前可以更改任何记录的发货条目,之后订单将被冻结。 (业务需求)

虽然这在现实世界的场景中可能不会发生...... 在我们的负载测试期间,我们收到 System.Data.Linq.ChangeConflictException 异常。 在事务中结束提交也无济于事。 我们不能强制 LINQ 在整个更新操作期间锁定行吗?

还有其他方法可以解决这个问题吗?

【问题讨论】:

  • 你是如何处理 LINQ 并发的?

标签: c# linq linq-to-sql concurrency transactions


【解决方案1】:

如果您对同一数据的并发更新确实存在问题,那么您可能会考虑在事务中执行整个操作 - 即获取数据提交它。只要您将 get/update/commit 视为短暂的原子操作(即您不会在中间暂停用户输入),就应该没问题。

特别是,使用可序列化的隔离级别,没有人可以更新您有读锁的数据(即您查询的任何内容)。唯一的问题是,如果不同的查询以不同的顺序读取数据,这可能会导致死锁。 AFAIK,没有办法让 LINQ-to-SQL 发出 (UPDLOCK) 提示,这是一种耻辱。

TransactionScope 或 SqlTransaction 都可以,只要将它们设置为可序列化隔离(这是 TransactionScope 的默认设置)。

【讨论】:

  • 嗨,感谢您的回复...我确实尝试将其包装在事务下,但我得到了一个不同的异常...该操作是死锁的受害者。亲切的问候,Ashish Sharma
  • 我想知道这是锁升级死锁还是不同顺序的死锁?如果是前者,一个选项(尽管您失去了许多 LINQ 优势)可能是使用 SP 查询数据 - 然后您可以包含 UPDLOCK 提示,防止锁升级问题。
  • (仍然通过 LINQ,我的意思是 - 即告诉设计者此 SP 返回此表)
  • 如果您想在事务中设置更新锁,您始终可以使用 ExecuteQuery 来执行此操作,然后使用 L2S 对象进行其余工作。示例:forums.microsoft.com/msdn/…
  • (虽然描述的场景听起来像是我会避免使用数据库锁来处理并发性,而是在应用程序逻辑本身中构建“软锁定”机制......)
【解决方案2】:

您可能想查看Entity Framework,它将所有内容作为事务执行。这里有两个关于 Entity Framework 的播客也很有趣。

DNRTV - part 1 - part 2

【讨论】:

  • LINQ-to-SQL 也使用事务;这里的问题是同一个事务没有跨越 get 和 set - 但是对于 LINQ-to-SQL 或 EF 都是一样的。
【解决方案3】:

对于这种情况,即多个用户可能想要对同一记录/客户/订单/任何内容进行更改,最好在应用程序逻辑中构建“锁定”而不是使用数据库锁定。

使用数据库锁来解决数据的逻辑锁定会给您带来一堆新问题。一个更好的解决方案是有列和/或表,您可以在其中指示订单/客户/等正在[由用户]编辑,直到它被锁定等。查询该表(或列)以检查客户是否/order/thing 在允许其他用户编辑之前可供编辑。

见: http://forums.microsoft.com/MSDN/ShowPost.aspx?PostID=3984968&SiteID=1

【讨论】:

  • 能否请您修复损坏的链接?
  • 我希望可以。不幸的是,微软已经更新了 MSDN 论坛,并且在此过程中,他们删除了所有指向帖子/线程的链接,包括上面的链接。该线程仍然存在于某个地方,但我不记得它是哪一个......
猜你喜欢
  • 2010-09-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多