当前位置: 首页 > 知识库问答 >
问题:

如何使用Spring Boot Spring Data JPA单元测试悲观锁定

拓拔麒
2023-03-14

我想测试FooRepository.lock()是否工作,有人调用lock()后,其他人调用应该是等待。

以下是我的最佳尝试,它不起作用。我认为原因是entityManger和fooRepository都参与了同一事务。

如何从另一个事务调用lock()?或者对悲观锁的单元测试有什么建议?谢谢

Foo存储库测试:

package com.example.demo;

import java.util.UUID;

import javax.persistence.LockModeType;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest;
import org.springframework.boot.test.autoconfigure.orm.jpa.TestEntityManager;
import org.springframework.test.context.junit4.SpringRunner;

@RunWith(SpringRunner.class)
@DataJpaTest
public class FooRepositoryTest {

    @Autowired
    private TestEntityManager entityManager;    

    @Autowired
    private FooRepository fooRepository;

    @Test
    public void lockTest() {
        // given
        Foo foo = new Foo();
        foo.setName("foo-name");

        UUID fooId = fooRepository.save(foo).getFooId();
        entityManager.flush();
        entityManager.clear();

        // when
        Foo savedFoo = fooRepository.findOne(fooId);
        fooRepository.lock(savedFoo);

        // then
        // I want something like this to be lock wait,
        // something to confirm the above fooRepository.lock() work
        entityManager.getEntityManager().lock(savedFoo, LockModeType.PESSIMISTIC_WRITE);
    }

}

傅类:

package com.example.demo;

import java.util.UUID;

import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;

@Entity
public class Foo {  
    @Id
    @GeneratedValue
    private UUID fooId;

    private String name;

    public UUID getFooId() {
        return fooId;
    }

    public void setFooId(UUID fooId) {
        this.fooId = fooId;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

}

FooApplication类:

package com.example.demo;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class FooApplication {

    public static void main(String[] args) {
        SpringApplication.run(FooApplication.class, args);
    }
}

类 Foo存储库:

package com.example.demo;

import java.util.UUID;

import org.springframework.data.jpa.repository.JpaRepository;

public interface FooRepository extends JpaRepository<Foo, UUID>, FooRepositoryCustom {  
}

FooRepositoryCustom类:

package com.example.demo;

public interface FooRepositoryCustom {  
    public void lock(Foo foo);  
}

类FooRepositoryImpl:

package com.example.demo;

import javax.persistence.EntityManager;
import javax.persistence.LockModeType;

import org.springframework.beans.factory.annotation.Autowired;

public class FooRepositoryImpl implements FooRepositoryCustom {

    @Autowired
    private EntityManager entityManager;

    @Override
    public void lock(Foo foo) {
        entityManager.lock(foo, LockModeType.PESSIMISTIC_WRITE);
    }   
}

共有1个答案

谷奕
2023-03-14

你把单元测试弄错了。

您编写单元测试不是为了行使某些第三方框架实现的功能。单元测试是为您的单元准备的!

换句话说:您不需要验证锁定是否按预期工作。您的单位可以:

entityManager.lock(foo, LockModeType.PESSIMISTIC_WRITE);

因此,您唯一可以考虑在这里进行测试的是:确保使用预期的参数调用实体管理器lock()方法。

意思是:验证你的代码是否使用了你认为应该使用的框架——但是不要去测试其他人的代码!你看——当你的单元测试显示框架是错误的时候,你会怎么做…你不能改变它!(当然,你可以写一个错误报告)

免责声明:在特殊情况下,您可能会假设某个第三方产品存在错误——那么编写一个单元测试来测试这个假设可能非常有用。这样您以后就可以针对该产品的新版本运行单元测试,看看错误是否仍然存在。

 类似资料:
  • 问题内容: 我正在使用Criteria API检索hibernate中的对象列表。但是,我需要锁定那些对象,因为同时执行的另一个线程将获得确切的对象,并且在没有悲观锁定的情况下,只有一个线程会成功。 我尝试如下,但它不起作用。 更新 :我正在执行此语句之后的更新,以便我希望两个线程都读取不同的行,或者至少第二个线程应该等到第一个线程完成事务并离开锁。 hibernate生成的查询如下。 更新 :这

  • 悲观锁:假定会发生并发冲突,屏蔽一切可能违反数据完整性的操作 乐观锁:假设不会发生并发冲突,只在提交操作时检查是否违反数据完整性。 乐观锁与悲观锁的具体区别: http://www.cnblogs.com/Bob-FD/p/3352216.html

  • 问题内容: 我在java下有spring项目,使用hibernate查询,我喜欢使用悲观锁定。 在Spring + Hibernate中如何进行悲观锁定? 编辑: 问题: 我想在一个方法中使用悲观锁定,并且我将此方法称为从不同的方法。当我从第一个方法调用它时,悲观的工作效果很好,但是当我从第二个方法调用它时,它给出了(无法提交事务) 例外: 问题答案: http://www.amicabile.c

  • 这是令人难以置信的沮丧…我正在使用Couchbase v3 C API,我遇到了一个问题,这个问题可以通过使用他们的“悲观”锁定来完美解决。经过一番努力,我相信我终于找到了如何使用它锁定记录(使用,它大概需要一个以微秒为单位的参数),但是我不知道如何在完成后解锁记录,除了让它超时,这不是一个可以接受的解决方案。 这里的文档提供了一个示例,但出于某种未知的原因,它使用的是Javascript而不是C

  • 本文向大家介绍说一下乐观锁和悲观锁?相关面试题,主要包含被问及说一下乐观锁和悲观锁?时的应答技巧和注意事项,需要的朋友参考一下 乐观锁:每次去拿数据的时候都认为别人不会修改,所以不会上锁,但是在提交更新的时候会判断一下在此期间别人有没有去更新这个数据。 悲观锁:每次去拿数据的时候都认为别人会修改,所以每次在拿数据的时候都会上锁,这样别人想拿这个数据就会阻止,直到这个锁被释放。 数据库的乐观锁需要自

  • 嗨, 我们有一个应用程序(J2EE/Hibernate/JPA),其中有几个用户在一个公共实体上执行操作。 句子是单独的实体 几个用户同时更新同一句话的几率很低 在这种情况下,其中一个用户可以收到消息“对不起另一个用户试图编辑相同的句子” 到目前为止还不错。 但是现在,我们已经为这个应用程序添加了后台进程(相当快的进程)。他们经常做出改变(假设它将一个词的出现替换为另一个词)。 这是不能接受的向用