C# LINQ to SQL 和并发问题

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/190666/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-03 17:23:24  来源:igfitidea点击:

LINQ to SQL and Concurrency Issues

c#linqlinq-to-sqlconcurrencytransactions

提问by SharePoint Newbie

We are trying to build a High-Volume Orders Record System. There are three primary tables: 1. Orders 2. OrderDetails 3. OrderShipment

我们正在尝试建立一个大批量订单记录系统。有三个主要表: 1. Orders 2. OrderDetails 3. OrderShipment

The Shipment table contains n record per order and any record shipment entry can be changed before the Customer accepts th order, after which it is frozen. (A business requirement)

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

Although this may not happen in real world scenarios... during our load tests, we are getting System.Data.Linq.ChangeConflictException exceptions. Wrapping up the submit inside a transacion is not helping either. Can't we force LINQ to get a lock on the row for the entire duration of the update operation?

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

Is there any other way to get over this?

有没有其他方法可以克服这个问题?

采纳答案by Marc Gravell

If you are having genuine issues with concurrent updates on the same data, then you might consider performing the entire operation in a transaction - i.e. getting the data andcommitting it. As long as you treat the get/update/commit as a short-lived, atomic operation (i.e. you don't pause for user-input in the middle) it should be OK.

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

In particular, with a serializable isolation level, nobody can update data that you have a read lock on (i.e. anything you have queried). The only problem is that this might lead to deadlock scenarios if different queries are reading data in different orders. AFAIK, there is no way to get LINQ-to-SQL to issue the (UPDLOCK) hint, which is a shame.

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

Either a TransactionScope or a SqlTransaction would do, as long as they are set as serializable isolation (which is the default for TransactionScope).

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

回答by Alexandre Brisebois

you may want to look into Entity Frameworkwhich executes everything as a transaction. Here are two podcasts which can also be interesting about Entity Framework.

您可能想要查看将所有内容作为事务执行的实体框架。这里有两个关于实体框架的播客也很有趣。

DNRTV - part 1- part 2

DNRTV -第 1部分- 第 2 部分

回答by KristoferA

For this kind of situations, i.e. where more than one user may want to make changes to the same record/customer/order/whatever it is better to build "locking" into the application logic rather than use database locks.

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

Using DB locks to solve logical locking of data is going to present you with a heap of new issues. A better solution is to have columns and/or tables where you can indicate that an order/customer/etc is being edited [by a user], until when it is locked etc. Query that table (or columns) to check if the customer/order/thing is available for editing before allowing another user to edit it.

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

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

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