标签: optimistic-locking

Hibernate:我应该将'version'字段包含在hashcode()和equals()方法中

我知道,当覆盖hashcode()equals()我的持久化实体的我不应该包括ID,只包括有意义的属性唯一标识对象.但是Hibernate version用于乐观并发控制的字段呢?我应该跳过它,就像ID一样吗?如果让我们说new User(name='John', version=1).equals(new User(name='John',version=2)),不管怎么说它不会混淆Hibernate OCC呢?

hibernate version hashcode optimistic-locking optimistic-concurrency

6
推荐指数
1
解决办法
830
查看次数

使用Hibernate和Spring实现乐观锁

我正在尝试按顺序实现乐观锁定以避免丢失更新情况.在我的应用程序中,两个用户获取相同的记录,第一个用户通过一些更改更新它.查看相同记录的第二个用户看不到此更改,他自己进行了一些更改并对其进行了更新.由此导致第一批人员失去了.为了防止这种情况,我写了以下内容,但问题仍然存在.我是这个概念的新手,无法识别问题.

我试图通过阅读doc 11.3.4 来实现这一目标.自定义自动版本控制部分.

  • 配置文件

    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:mvc="http://www.springframework.org/schema/mvc"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:tx="http://www.springframework.org/schema/tx"
    xsi:schemaLocation="
    http://www.springframework.org/schema/beans
    http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
    http://www.springframework.org/schema/tx
    http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
    http://www.springframework.org/schema/mvc
    http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd">
    
    <tx:annotation-driven transaction-manager="txManager"/>
    
    <bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
      <property name="dataSource" ref="dataSource"/>
    </bean>
    
    <bean id="hibernateTemplate" class="org.springframework.orm.hibernate3.HibernateTemplate">
      <property name="sessionFactory" ref="sessionFactory"/>
    </bean>
    
    <bean id="sessionFactory" class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
      <property name="dataSource" ref="dataSource"/>
      <property name="annotatedClasses">
        <list>
            <value>server.bo.Dept</value>
            <value>server.bo.Emp</value>
        </list>
      </property>
      <property name="hibernateProperties">
        <props>
            <prop key="hibernate.dialect">org.hibernate.dialect.SQLServer2008Dialect</prop>
            <prop key="hibernate.show_sql">false</prop>
        </props>
      </property>
    </bean>
    <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
      <property name="driverClassName" value="net.sourceforge.jtds.jdbc.Driver"/>
      <property name="url" value="${db.url}"/>
      <property name="username" value="${db.username}"/>
      <property name="password" value="${db.password}"/>
    </bean>
    <bean id="deptDAO" class="server.dao.DeptDAOImpl">
      <property …
    Run Code Online (Sandbox Code Playgroud)

spring hibernate optimistic-locking optimistic-concurrency

6
推荐指数
1
解决办法
3万
查看次数

NHibernate 无法将数据库状态与会话同步

我在检查NHibernate的日志文件时,发现了一些随机错误,如下:

NHibernate.StaleObjectStateException: Row was updated or deleted by another transaction (or unsaved-value mapping was incorrect): [MaltaIndependent.Modules._AutoGen.MemberImpl#353796206]
   at NHibernate.Persister.Entity.AbstractEntityPersister.Update(Object id, Object[] fields, Object[] oldFields, Object rowId, Boolean[] includeProperty, Int32 j, Object oldVersion, Object obj, SqlCommandInfo sql, ISessionImplementor session) in c:\Repository\Work\CodeBase\C#\+OpenSource\nHibernate\nhibernate-core-master-v3.3.1\src\NHibernate\Persister\Entity\AbstractEntityPersister.cs:line 2821
   at NHibernate.Persister.Entity.AbstractEntityPersister.UpdateOrInsert(Object id, Object[] fields, Object[] oldFields, Object rowId, Boolean[] includeProperty, Int32 j, Object oldVersion, Object obj, SqlCommandInfo sql, ISessionImplementor session) in c:\Repository\Work\CodeBase\C#\+OpenSource\nHibernate\nhibernate-core-master-v3.3.1\src\NHibernate\Persister\Entity\AbstractEntityPersister.cs:line 2702
   at NHibernate.Persister.Entity.AbstractEntityPersister.Update(Object id, Object[] fields, Int32[] dirtyFields, Boolean hasDirtyCollection, Object[] oldFields, Object oldVersion, Object obj, Object …
Run Code Online (Sandbox Code Playgroud)

c# nhibernate concurrency optimistic-locking

5
推荐指数
1
解决办法
3748
查看次数

没有CQRS的域事件和版本控制

嗨,我有以下senario,我不明白如何获得最终的一致性:

  1. 用户1使用基于任务的ui来更改客户名称
  2. App Service调用聚合操作
  3. 客户名上的聚合火灾事件已更改
  4. 总线使用nservicebus发送消息
  5. NServicebus服务终止
  6. 用户2获取聚合并调用更改地址
  7. 聚合操作调用
  8. 域事件被触发
  9. 消息放在公交车上
  10. 总线重启
  11. 消息2首先被捕获
  12. 处理消息2并使用新地址更新其他有界上下文
  13. 消息1现在拾起,这是错误的顺序
  14. 现在发生了什么

如果我们在事件中传递聚合的版本,那么在13中会出现乐观的并发错误吗?

如果是,则将消息1新应用于其他上下文中的对象.我们如何保持一致性?

这是阻止我在我的域中应用事件的问题.欢迎所有帮助.

基本思想是在另一个上下文中更新另一个聚合.我只是坚持这个并发技术.

我们不是在命令处理程序和命令推送总线的意义上使用事件源或CQRS.只有事件处理我们想要异步发生,因为我们有一个我们不希望改变的现有设计.

布莱尔

domain-driven-design event-handling eventual-consistency optimistic-locking domain-events

5
推荐指数
1
解决办法
677
查看次数

乐观锁定绝对安全吗?

当使用乐观锁定策略时,它可以解决如下的并发问题:

| the first transaction started        |
|                                      |  
| select a row                         |
|                                      |  the second transaction started
| update the row with version checking |
|                                      |  select the same row 
| commit txn                           |
|                                      |  update the row with version checking
|                                      |  
|                                      |  rolls back because version is dirty

但是,如果在极少数情况下,第二个事务中的更新是在第一个事务中的udpate之后但是在事务提交之前呢?

| the first transaction started        |
|                                      |  the second transaction started
| select a row                         |
|                                      |  select the same row …

optimistic-locking

5
推荐指数
1
解决办法
538
查看次数

Grails 2.3.7 Optimistic Locking 版本在每次提交命令对象时更新

我有以下

def save(ACommand command){
  ...
}

@Validateable
class ACommand implements Serializable
{
  ADomainObject bundleDef
}
Run Code Online (Sandbox Code Playgroud)

但每次 save 被调用时,版本都会增加。因此,如果我打开两个浏览器并连续提交不同的值,而不是像我预期的那样第二次出错,而是更新了值。

我也尝试使用两个不同的会话没有区别

更新

如果我使用断点并在另一个断点完成之前提交它工作正常。但是,如果我让第一个完成,然后在不刷新的情况下提交第二个,则版本将更新为较新的(我不想要的)并且更改会通过。

更新 2

当您执行更新时,Hibernate 将自动根据数据库中的 version 列检查 version 属性,如果它们不同,将抛出 StaleObjectException。如果事务处于活动状态,这将回滚事务。

每个 Grails这在我看来应该有效。

grails grails-orm optimistic-locking

5
推荐指数
1
解决办法
856
查看次数

JPA 中删除实体时的乐观锁定

EJB 中使用 CMT 的事务方法可删除提供的实体:

public boolean delete(Entity entity) {
    Entity managedEntity = entityManager.find(Entity.class, entity.getId());

    if (managedEntity == null) {
        throw new EntityNotFoundException();
    }

    entityManager.remove(managedEntity);
    return !entityManager.contains(managedEntity);
}
Run Code Online (Sandbox Code Playgroud)

关联的客户端提供的实体是分离的实体。该entityManager.remove()操作生成DELETE如下 DML 语句:

public boolean delete(Entity entity) {
    Entity managedEntity = entityManager.find(Entity.class, entity.getId());

    if (managedEntity == null) {
        throw new EntityNotFoundException();
    }

    entityManager.remove(managedEntity);
    return !entityManager.contains(managedEntity);
}
Run Code Online (Sandbox Code Playgroud)

如果数据库中的行版本与实体中的行版本冲突,则附加检查AND (version = ?)应导致抛出 。javax.persistence.OptimisticLockException

javax.persistence.OptimisticLockException然而,即使提供的实体要在另一个会话中由另一个用户同时修改,这也不会抛出异常,因为它是由客户端(Web 或其他方式)最后读取的,因为该find()方法在另一个事务中获取具有更新的行版本的实体(旧的/过时的行版本(由 标记@javax.persistence.Version)仅包含在作为方法参数提供的分离实体中)。

与 不同的是EntityManager#merge(T entity)EntityManager#remove(Object entity) …

hibernate jpa eclipselink optimistic-locking

5
推荐指数
1
解决办法
4178
查看次数

当一个不存在的实体被传递给 merge() 时,Hibernate 意外地发出 INSERT 而不是抛出 javax.persistence.OptimisticLockException

客户端应用程序提供了一个陈旧的实体,该实体将被 Hibernate 合并。举个很简单的例子。

public Entity update(Entity entity) {
    return entityManager.contains(entity) ? entity : entityManager.merge(entity);
}
Run Code Online (Sandbox Code Playgroud)

Entity例如,是由 Web 应用程序提供的分离的、陈旧的实体。该方法在活动的 JTA 事务(或本地资源)中执行。

乐观锁已通过引入 @Version在给定的实体中字段,。

当要合并的实体已经被删除时,javax.persistence.OptimisticLockException预计会抛出这不会发生的情况。Hibernate 执行INSERT,这是完全出乎意料的。插入一个陈旧的实体而不是抛出javax.persistence.OptimisticLockException是有悖于锁定的。

“插入或更新”是一个分开的故事,应该通过抛出 javax.persistence.OptimisticLockExceptionmerge(),如果实现了乐观锁定,如果过时或已删除(不存在)的实体被传递给。

javax.persistence.OptimisticLockException如果过时或已删除/不存在的实体被传递给,EclipseLink 会按预期抛出merge()

javax.persistence.OptimisticLockException当一个陈旧或不存在的实体被传递给时,有没有办法让 Hibernate 抛出,merge()

我希望应该有一些可配置的属性 persistence.xml全局应用程序范围内应用它,或者使用注释将它应用到特定实体。

我目前使用的是 Hibernate 5.0.5 final。


更新到 Hibernate 5.0.6 最终版。

merge hibernate jpa optimistic-locking

5
推荐指数
1
解决办法
627
查看次数

使用乐观锁会不会出现死锁?

众所周知,有两种锁定策略:乐观锁定与悲观锁定

悲观锁定是当您锁定记录以供您独占使用,直到您完成它为止。它比乐观锁具有更好的完整性,但要求您在应用程序设计时要小心以避免死锁

还知道,乐观并发控制多版本并发控制(Oracle 或 MSSQL-Snapshot/MVCC-RC)不同:乐观与多版本并发控制 - 差异?

但是如果在两个事务中都使用 OCC(乐观并发控制),是否会在两个事务之间发生死锁?

我们能说乐观锁通过降低一致性来降低死锁的可能性吗?并且只有当每个更新都在一个单独的事务中时,死锁的可能性才为 0%,但这样的一致性最小。

sql-server oracle locking optimistic-locking pessimistic-locking

5
推荐指数
2
解决办法
3135
查看次数

JPA 乐观锁定:如果记录已更新,如何防止删除,反之亦然?

我需要我的应用程序具有以下行为:

场景1

  1. 用户A查看订单。

  2. 用户B查看相同的订单。

  3. 用户A删除订单。
  4. 用户B请求更新订单。这应该会失败。

场景2

  1. 用户A查看订单
  2. 用户B查看同一条订单
  3. 用户 A 更新订单。
  4. 用户B请求删除订单。这应该会失败。

使用 JPA(Hibernate via Spring Data JPA),我尝试用来@Version实现这种乐观锁定行为:

@Entity
public class Order {

    @Id
    @GeneratedValue(strategy=GenerationType.IDENTITY)
    private Long id;

    @Version
    private Integer version;

    // many other fields
Run Code Online (Sandbox Code Playgroud)

删除时,UI 客户端向服务器提供订单 ID 列表以及每个订单 ID 的版本号。这篇文章(Spring Data JPA:删除乐观锁定语义)提到了一个标准解决方案:

if (entity.getVersion() != dto.getVersion()) {
    throw new OptimisticLockException("...");
}
Run Code Online (Sandbox Code Playgroud)

要使用这个,我必须

  1. 使用客户端的订单 ID 从数据库查找实体
  2. 将实体版本与客户端的 DTO 版本进行比较
  3. 执行删除。

问题是在步骤 2 中实体和 DTO 版本可能相同。但到了第3步,版本可能会有所不同。有没有办法让 hibernate 作为单个原子操作执行检查和更新,例如:

 delete from [Order] where orderId = ? …
Run Code Online (Sandbox Code Playgroud)

hibernate jpa optimistic-locking spring-data-jpa

5
推荐指数
0
解决办法
1299
查看次数