1

我对乐观并发异常有些怀疑。

好吧,例如,我从数据库中检索一些数据,修改一些寄存器,然后提交更改。如果有人在我的请求和我的更新之间更新了寄存器的信息,我会得到一个乐观的异常。经典的并发问题。

我的第一个疑问如下。EF判断信息是否改变,从数据库中检索数据,并将我获得的原始数据与从数据库中检索的数据进行比较。如果存在差异,则抛出乐观并发异常。

如果当我捕捉到乐观并发异常时,我决定是客户赢还是商店赢。在此步骤中,EF 再次检索信息还是使用第一次检索的数据?因为如果再次检索数据,将是低效的。

第二个疑惑是如何控制乐观并发异常。在 catch 代码块中,我决定是客户获胜还是商店获胜。如果客户赢了,那么我再次调用 saveChanges。但是在我决定客户端获胜和保存更改之间,其他用户可以更改数据,所以我再次得到一个乐观并发异常。理论上,它可能是一个无限循环。

使用事务(范围)来确保客户端更新数据库中的信息是个好主意吗?其他解决方案可以使用循环尝试 N 次更新数据,如果不可能,退出并告诉用户。

交易会是个好主意吗?它会消耗大量数据库资源吗?虽然事务会暂时阻塞数据库,但它确保更新操作完成。循环N次尝试完成操作,调用数据库N次,可能需要更多的资源。

谢谢。戴姆洛克。

编辑:我忘了问。是否可以将上下文设置为默认使用客户端获胜而不是等待并发异常?

4

1 回答 1

5

我的第一个疑问如下。EF 决定是否更改信息,从数据库中检索数据...

它不会从数据库中检索任何其他数据。它获取用于并发处理的实体的原始值,并在更新命令的 where 条件下使用它们。更新命令之后是选择修改的行数。如果数字为 0,则表示该记录不存在或有人更改了它。

第二个疑惑是如何控制乐观并发异常。

您只需调用Refreshand SaveChanges。如果需要,您可以重复几次模式。如果您有如此多的高并发应用程序,以至于多个线程争先恐后地在几秒钟内更新相同的记录,那么您很可能需要以不同的方式构建您的数据存储。

使用事务(范围)来确保客户端更新数据库中的信息是个好主意吗?

SaveChanges总是使用数据库事务。TransactionScope 不会为您增加任何额外的价值,除非您想通过多次调用使用事务SaveChanges、分布式事务或更改事务的隔离级别等。

是否可以将上下文设置为默认使用客户端获胜而不是等待并发异常?

它是默认设置的。简单地不要标记您的任何属性,ConcurrencyMode.Fixed您将没有并发处理 = 客户获胜。

于 2012-05-28T09:44:27.333 回答