Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/379.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/spring/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/selenium/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 弹簧数据积存和悲观锁_Java_Spring_Spring Data_Spring Data Jpa - Fatal编程技术网

Java 弹簧数据积存和悲观锁

Java 弹簧数据积存和悲观锁,java,spring,spring-data,spring-data-jpa,Java,Spring,Spring Data,Spring Data Jpa,我正在使用 弹簧靴1.4.2 Spring数据JPA 1.10.5 PostgreSQL 9.5数据库 我希望在Spring数据存储库中有一个带有悲观锁的findOne方法,该方法与已经提供的findOne方法分离 我写道: 您需要使用Spring为您创建的entityManger事务: @Transactional public void doSomething(long id){ // Both threads read the same version

我正在使用

  • 弹簧靴1.4.2
  • Spring数据JPA 1.10.5
  • PostgreSQL 9.5数据库
我希望在Spring数据存储库中有一个带有悲观锁的
findOne
方法,该方法与已经提供的
findOne
方法分离

我写道:


您需要使用
Spring
为您创建的
entityManger事务

    @Transactional
    public void doSomething(long id){
        // Both threads read the same version of the data 
        Registration registrationQueriedTheFirstTime = registrationRepository.findOne(id);

        // First thread gets the lock, second thread waits for the first thread to have committed
        Registration registration = registrationRepository.findOnePessimistic(id);
        // I need this to have this statement, otherwise, registration.getStatus() contains the value not yet updated by the first thread
        entityManager.refresh(registration);

        EntityManager em = EntityManagerFactoryUtils.getTransactionalEntityManager(<Your entity manager factory>);
        em.refresh(registration);
        registration.setStatus(newStatus);
        registrationRepository.save(registration);
    }

}
@Transactional
公共无效剂量测定(长id){
//两个线程都读取相同版本的数据
Registration Registration QueriedTheFirstTime=registrationRepository.findOne(id);
//第一个线程获得锁,第二个线程等待第一个线程提交
Registration=registrationRepository.findOnePessimistic(id);
//我需要这个语句,否则,registration.getStatus()包含第一个线程尚未更新的值
entityManager.refresh(注册);
EntityManager em=EntityManager工厂utils.getTransactionalEntityManager();
em.refresh(注册);
注册。设置状态(newStatus);
registrationRepository.save(注册);
}
}

您必须向我们显示更改实体值的代码。为什么在只读取实体的方法上使用“悲观写入”锁定表?我在注释为
@Transactional
的方法中使用代码,在该方法中,我读取实体,更新实体,然后将其写回。相当标准。我想避免这个操作的并发性,所以我想使用悲观锁。我只想在
更新
之前执行
选择更新
。整个代码块是事务性的,因此使用相同的entitymanager。
EntityManager
充当一级缓存。首先检索不带锁的对象,然后使用锁再次检索对象。但是在第一级缓存中,您将检索该对象,而不是新的DB对象。这就是
EntityManager
的基本工作方式,如果您不想这样做,您首先必须
清除
实体管理器。或者更确切地说,为什么您首先在同一个tx中检索它而不使用锁(这在imho中很奇怪)。我希望
crudepository
在指定悲观锁的情况下从一级缓存中清除该实体……问题不在于悲观锁在我的情况下有多相关,问题是为什么SpringDataJPA不使用锁定在DB中的值刷新缓存。。。仅供参考,我使用悲观锁定,因为它会对我的状态更新(例如发送电子邮件)产生无法回滚的副作用。如果我使用
entityManager.refresh
它就可以正常工作。我只是希望我不需要那个。该代码目前在生产中运行良好。@RahulGupta似乎没有问题,rcomblen只是好奇为什么他必须手动刷新
public interface RegistrationRepository extends CrudRepository<Registration, Long> {

    @Lock(LockModeType.PESSIMISTIC_WRITE)
    @Query("select r from registration_table r where r.id = ?1")
    Registration findOnePessimistic(Long id);

}

public void RegistrationService {

    @Transactional
    public void doSomething(long id){
        // Both threads read the same version of the data 
        Registration registrationQueriedTheFirstTime = registrationRepository.findOne(id);

        // First thread gets the lock, second thread waits for the first thread to have committed
        Registration registration = registrationRepository.findOnePessimistic(id);
        // I need this to have this statement, otherwise, registration.getStatus() contains the value not yet updated by the first thread
        entityManager.refresh(registration);

        registration.setStatus(newStatus);
        registrationRepository.save(registration);
    }
}
    @Transactional
    public void doSomething(long id){
        // Both threads read the same version of the data 
        Registration registrationQueriedTheFirstTime = registrationRepository.findOne(id);

        // First thread gets the lock, second thread waits for the first thread to have committed
        Registration registration = registrationRepository.findOnePessimistic(id);
        // I need this to have this statement, otherwise, registration.getStatus() contains the value not yet updated by the first thread
        entityManager.refresh(registration);

        EntityManager em = EntityManagerFactoryUtils.getTransactionalEntityManager(<Your entity manager factory>);
        em.refresh(registration);
        registration.setStatus(newStatus);
        registrationRepository.save(registration);
    }

}