我对乐观并发异常有些怀疑。
好吧,例如,我从数据库中检索一些数据,我修改了一些寄存器然后提交更改。如果有人在我的请求和我的更新之间更新寄存器的信息,我会得到一个乐观的例外。经典的并发问题。
我的第一个疑问如下。 EF确定信息是否更改,从数据库中检索数据,并将我获得的原始数据与从数据库中检索的数据进行比较。如果存在差异,则抛出乐观并发异常。
如果我抓住乐观并发异常,我会决定客户端是赢还是商店获胜。在这一步中EF再次检索信息或使用第一次检索的数据?因为如果再次检索数据,那将是低效的。
第二个疑问是如何控制乐观并发异常。在catch代码块中,我决定客户端是赢还是商店获胜。如果客户端获胜,那么我再次调用saveChanges。但在我决定客户端获胜和保存更改之间,其他用户可能会更改数据,因此我再次获得乐观并发异常。从理论上讲,它可能是一个无限循环。
使用事务(范围)来确保客户端更新数据库中的信息是一个好主意吗?其他解决方案可以使用循环尝试N次更新数据,如果不可能,退出并将其告诉用户。
交易是个好主意吗?它会占用数据库的大量资源吗?虽然事务会暂时阻塞数据库,但它确保了更新操作的完成。 N次循环尝试完成操作,调用数据库N次,也许可能需要更多资源。感谢。 Daimroc。
编辑:我忘了问。是否可以将上下文设置为默认使用客户端获胜而不是等待并发异常?答案 0 :(得分:5)
我的第一个疑问如下。 EF决定信息是否正确 是否更改,从数据库中检索数据......
它不会从数据库中检索任何其他数据。它使用用于并发处理的实体的原始值,并在更新命令的where条件中使用它们。更新命令之后是选择修改行的数量。如果数字为0,则表示记录不存在或者有人更改了记录。
第二个疑问是如何控制乐观并发异常。
您只需致电Refresh
和SaveChanges
即可。如果需要,您可以重复几次图案。如果您有这么多高度并发的应用程序,多个线程正在努力在几秒钟内更新相同的记录,那么您很可能需要以不同的方式构建数据存储。
使用事务(范围)来确保客户端更新数据库中的信息是不是一个好主意?
SaveChanges
始终使用数据库事务。除非您希望使用事务多次调用SaveChanges
,分布式事务或更改事务的隔离级别,否则TransactionScope不会为您添加任何其他值。
是否可以将上下文设置为默认使用客户端获胜 等待并发异常?
默认设置。只是不要使用ConcurrencyMode.Fixed
标记任何属性,并且您将没有并发处理=客户获胜。