问题标签 [optimistic-locking]

For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.

0 投票
2 回答
14833 浏览

java - 如何从 Java 代码编写乐观和悲观锁定

我知道乐观锁和悲观锁是什么,但是当你写一个java代码时你是怎么做的呢?假设我在 Java 中使用 Oracle,我在 JDBC 中是否有任何方法可以帮助我做到这一点?我将如何配置这个东西?任何指针将不胜感激。

0 投票
0 回答
452 浏览

web-services - 是否有用于乐观锁定的 Web 服务 (WS) 标准?

是否有针对互操作性设计的乐观锁定/乐观并发控制(OCC) 的 Web 服务标准 (WS*)?

有许多与悲观并发控制机制相关的标准,例如WS-AtomicTransaction,但据我所知,它没有提供与乐观锁定相关的版本或时间戳处理功能。

我找到了一篇关于Optimistic locking and WCF的文章,但没有市长标准。是否有这样的,或者您是否知道您想推荐的其他示例或模式?

0 投票
1 回答
1199 浏览

web-services - 如何在 Web 服务更新消息 (DTO) 中使用可选属性?

背景

假设您有一个 (SOAP) Web 服务,BookService用于管理图书馆中的书籍。在信息模型中假设Book实体具有以下属性:

  • id
  • author
  • publisher
  • title
  • shelfId

为了操作数据,定义了四个 Web 服务操作:

  • AddBook
  • GetBook
  • UpdateBook
  • DeleteBook

为每个操作定义请求和响应消息。但是,更新消息 XML 模式的设计更为复杂。我们希望达到以下品质:

  • R1:重置/删除属性的先前值的可能性。例如,说您不再将书保留在图书馆中,因此想重置/清空/删除该shelfId特定书的属性的属性值。
  • R2:避免网络服务中的喋喋不休。请参阅反模式 Chatty Services
  • R3:为未来对并发控制和乐观锁定的需求做准备。我们可能希望最小化(或消除)根据旧信息进行更新的风险。

设计方案

我看到了三个市长备选方案,其中一个有几个子选项来设计更新消息:

  1. 发送整个业务文件。被遗漏的元素(minOccurs="0"在模式中)或元素明确设置为空,即<shelfId xsi:nil="true"/>,将被解释为删除先前的值。
  2. 突出显示更改或仅发送差异。
    1. 发送整个业务文档,但使用特定于此目的的属性标记修改的元素。示例:<author dirty="true">Hemingway<author/>。然后,服务的提供者只更新那些标记为脏的元素并忽略其他元素。
    2. 在消息模式中,将除标识符之外的所有元素设置id为具有minOccurs="0"。消费者发送那些要修改的元素。遗漏的元素不能在语义上被解释为删除。为了删除一个值,NULL必须使用显式 XML 值。示例:<shelfId xsi:nil="true"/>
    3. 发送整个业务文件,同时提交之前阅读文件的副本。然后,提供者可以比较两个文档并更新新文档和先前文档不同的那些属性。
  3. 定义多个操作。不是只使用一个操作,而是UpdateBook根据您认为必须更新的元素定义多个操作,例如UpdateBookAuthorUpdateBookPublisher等等。这些中的每一个都将只有强制元素,并且要删除元素,请使用 XML 的显式 NULL,例如<shelfId xsi:nil="true"/>.

讨论

替代 3的优点是易于理解,但缺点是消费者需要调用多个操作,以防Book要更新实体中的多个字段。这使得服务“健谈”(参见上面的 R3),从而导致性能下降。

Alt 2Alt 1更复杂,但Alt 2有一些与乐观并发控制相关的优点:

  • 对于每个字段的时间戳/版本的乐观锁定存储在数据库中的情况(例如authorVersion)=> Alt 2提供了一种让多个用户同时修改相同部分的不同部分的方法,例如authorpublisherBook同时发生故障的风险较小。
  • 对于在数据库中存储一个完整的单个时间戳/版本的乐观锁定的情况=> Alt 2相对于Alt 1Book没有真正的优势。即使更新只修改了一个字段,请求的版本号太旧也会导致错误。
  • 对于不使用并发控制或乐观/悲观锁定的情况 =>替代2比替代1提供的覆盖旧数据的风险更小,但其他不一致的更改可能会带来问题。

还有另一种情况,其中Alt 2(和Alt 3 )比Alt 1具有优势。消费者可能不会存储有关Book实体的所有数据。例如,如果机器人在更新书架信息时不需要跟踪(缓存)关于作者的信息,而只需要跟踪书架,则可以更有效地对从书架上挑选书籍的机器人进行编程。

替代2.3中的方法的一个优点是,消费者提交以前版本的完整副本而不是版本号或时间戳,即版本号或时间戳不需要数据库中的专用列。

总而言之,我会说Alt 2.2在大多数情况下看起来是最有吸引力的。这里的挑战在于反序列化 XML 的框架必须能够区分遗漏元素和显式设置为 NULL 的元素,例如<shelfId xsi:nil="true"/>. 在此处查看有关此主题的帖子。

问题

您会选择哪种选择?您是否看到其他更好的选择?你怎么看讨论?

0 投票
0 回答
399 浏览

sql-server-2008 - OptimisticLockException - Sql Server - 句柄

我正在尝试使用 GridViewControl 的一种方法更新数据库中的记录。它正在引发 OptimisticLockException。在我的数据库中,我有四个日期字段(dZadOpenDateTime、dZadCloseDateTime、dCreatedDateTime、dChangedDateTime)显示在这张图片http://imageshack.us/photo/my-images/854/exception.jpg/

你能给我一些提示如何处理这个异常吗?

0 投票
2 回答
2661 浏览

django - 在 Django REST 应用程序中使用 ETag 进行乐观锁定

我正在尝试为 Django 选择一个 REST 框架,这将使我能够轻松地使用 ETags 进行乐观锁定。我计划检查 Django-pistons 和 Django Rest Framework 库,但我对任何非 GPL 解决方案持开放态度(企业许可要求阻止我使用这些解决方案)。

我的应用程序正在以 JSON/YAML 形式从 SQLAlchemy 模型(不是 Django 模型)出售数据,并且模 ETag 问题与 Django Rest 框架一起工作得很好。但是,我看不到在我的视图上应用 ETag 标头的简单方法。

就我的观点而言,我想这样做:

  1. 给定一个响应,轻松地将 ETag 添加到我成功发送的响应标头中。这必须由我计算,因为它将取决于模型;对响应值或类似的东西进行散列是不够的。

  2. 在 POST/PUT 上,确保我收到的 ETag 与我发送的 ETag 匹配,或者拒绝该请求。

第 1 步给我带来了一些麻烦;我不确定哪个 REST 框架会使这变得最简单,我也不确定实现它的最佳方法是什么。

0 投票
1 回答
2072 浏览

java - 确定哪个实体导致了乐观锁异常

我有一个用 JSF 和 JPA 实现的 Web 应用程序。在 UI 中,用户可以在选择“保存”整个操作之前更新一堆不同的实体。在保存操作期间,如果两个用户正在交叉数据,其中一个将获得乐观锁异常,这一切都很好。但是,我希望在处理异常时能够分辨出哪个特定实体导致了 Optimistic Lock 异常,以便在 UI 中的正确行上显示标记。使用eclipselink,在优化锁异常的catch块中,有没有办法识别导致乐观锁异常的实体?

0 投票
3 回答
6702 浏览

hibernate - 如何使用 Hibernate 4 手动设置 @Version 字段?

环境:

我有那个User实体:

我有一个列出用户的搜索页面,然后单击用户进行编辑(userId在 URL 中给出)。

在编辑表单中,我在服务器上存储该实体的字段,当我保存我的用户时,我这样做:

问题:

因此,如果我正确理解了 Hibernate 的乐观锁定,如果我在浏览器中打开 2 个选项卡来编辑同一个用户,然后更新第一个选项卡上的登录名,然后更新第二个选项卡上的登录名,我应该有一个OptimisticLockException不应该?

实际上,我的应用程序不是这种情况......我验证了,form.getVersion()在两种情况下都返回相同的值,即使在第二次更新中,user.version第一次编辑已经更新了。

我错过了什么吗?

EntityManager产生了@RequestScoped(所以当我尝试合并时我在两个不同的EntityManagers 上......)。

我之前尝试entityManager.lock(user, LockModeType.OPTIMISTIC_FORCE_INCREMENT)entityManager.merge(...)如此处所述),但没有帮助。

我正在使用 Seam 3 和 JBoss 7.0.2.Final(它使用 Hibernate 4)。

0 投票
2 回答
1311 浏览

c# - 在哪里处理 StaleObjectStateException

try-catch我应该在 ASP.NET MVC 应用程序中的相应控制器内使用块(旨在 catch/handle )包装对存储库的调用,StaleObjectStateException还是应该在存储库实现中进行?

另外我该如何处理异常,通知用户。据我了解,没有回滚的意图?

谢谢!

0 投票
2 回答
542 浏览

java - 具有乐观锁定的活动记录模式 - 在更新前读取与在应用程序中存储版本?

我尝试使用 Java/JDBC 和 MySQL 以及用于并发处理的乐观锁定来实现活动记录模式。

现在,我有一个表中所有记录的“version_number”字段,每次更新后都会递增。

似乎有两种策略可以实现这一点:

  1. 应用程序在请求数据时还存储每个对象(即记录)的相应版本号。在更新时,版本号被“发送”到数据层,该数据层用于 UPDATE...SET...WHERE 查询以进行乐观锁定
  2. 应用程序不存储版本号,而只存储对象的某些部分(而不是整行数据)。为了使乐观锁定成功,数据层(活动记录)需要首先从数据库中获取“行”,获取版本号,然后触发相同的 UPDATE...SET...WHERE 查询以更新记录。

前者有“第一次获取”,然后是更新。在后一种情况下,您确实有一个“第一次提取”,但在更新之前有一个提取。

问题是:按照设计,哪种方法更好?将所有数据(包括版本号)存储在 Web 应用程序的前端(Javascript/HTML)中是否可以/安全/正确?还是在更新前对性能进行读取会更好?

有没有“正确的方法”来实现这个设计?我不确定活动记录的当前实现如何处理这个(Ruby、Play、ActiveJDBC 等)如果我要在 JDBC 中“原始”实现它,在这种情况下,正确的设计决策是什么?

0 投票
2 回答
5024 浏览

hibernate - Hibernate/JPA @Version 和 @Generated 导致 StaleObjectStateException

使用 Hibernate 4.1.0 提供的 Spring 3.1/JPA 2。

我的所有实体都有一个基类,它提供基本的审计功能(更新时间戳、版本号等)。因为其他应用程序访问我们的数据库,这些必须通过触发器设置。

我的映射看起来像:

提交事务时始终调用该org.hibernate.engine.internal.increment(...)方法 - 并导致StaleObjectStateException.

奇怪的是,如果我GenerationTime.NEVER在版本列上设置,休眠仍然会增加版本,但会正确保留。问题是即使数据库中的版本没有更新(例如,表上没有更改),从合并返回的版本也会比数据库值高 1,这显然会导致后续保存出现问题。

我的期望是GenerationTime.ALWAYS告诉hibernate永远不要尝试增加版本并依赖数据库来这样做,然后在插入/更新之后选择更新的值。

谁能告诉我我的理解和实施哪里出了问题?