Entity framework 如何在ORMs中实现一致的事务?

Entity framework 如何在ORMs中实现一致的事务?,entity-framework,orm,transactions,consistency,acid,Entity Framework,Orm,Transactions,Consistency,Acid,我的问题是概念性的 让我们假设我们使用ORM(如实体框架、Hibernate等)并在这些ORM中对域对象建模。由于ORM将为我们抽象出大多数SQL/do事务,我们如何确保事务的一致性 例如: 我们有一家网上书店卖书。如果我们出售一本书,我们基本上会使用类似的东西: var book = books.Single(b => b.Id == 42); book.Quantity -= 1; books.SaveChanges(); 但是,如果我正确理解了ORM,它们将只在更新查询中包装对书籍

我的问题是概念性的

让我们假设我们使用ORM(如实体框架、Hibernate等)并在这些ORM中对域对象建模。由于ORM将为我们抽象出大多数SQL/do事务,我们如何确保事务的一致性

例如: 我们有一家网上书店卖书。如果我们出售一本书,我们基本上会使用类似的东西:

var book = books.Single(b => b.Id == 42);
book.Quantity -= 1;
books.SaveChanges();
但是,如果我正确理解了ORM,它们将只在更新查询中包装对书籍的更改。这意味着您可能会遇到如下基本并发问题:

如果使用SQL,只需将.Quantity-=1包装在事务中,这样就安全了


在ORMs中,您通常如何以适当的方式处理此问题,或者是以某种方式自动处理此问题?

在更改数量之前,您必须先进行选择更新。这将锁定记录

这取决于您使用的ORM。使用Hibernate,您可以在执行查询时设置LockModeType

在Hibernate中,这将是LockModeType.悲观的

阅读Hibernate文档中有关锁定的更多信息:

实体框架用于此。大多数RDBMS系统不会使用事务来防止这种更新异常

UPDATE T SET Quantity = Quantity - 1 WHERE ID = :ID
这条语句将以原子方式运行,虽然使用一条语句可以防止更新丢失,但不能保证数量不会减少到零以下


悲观锁不仅需要事务,还需要锁定提示或提高事务隔离级别

如果更新查询只是最后的增量,那么我就不必使用select for update。因为一个update语句是原子的,所以不能有丢失的update?或者,您的意思是,如果不锁定“常用”orm,就不可能执行此操作?update语句是原子的,但这意味着您必须发出update语句,而不是使用orm选择数据,并使用orm进行更改和持久化数据。如果我错了,select和updateCorrect me之间会有一段时间,但是更高的事务隔离级别不会阻止这些异常,因为事务不会干扰。但我仍然不知道我在EF中该怎么做。将数量用作并发令牌将创建许多DbUpdateConcurrencyException,这不是问题吗?事务和更高的隔离级别将防止异常,但可能通过生成异常或死锁来实现。乐观并发总是通过创建异常来防止更新丢失。