我希望测试
FooRepository.lock()
是否有效,当某人调用 lock()
后,其他人呼叫它应该会等待。以下是我的最佳尝试,但并不起作用。我相信原因是 entityManger
和 fooRepository
都参与了同一个事务。如何从另一个事务中调用 lock()
?或者有没有关于悲观锁单元测试的建议?谢谢!FooRepositoryTest:
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);
}
}
类 Foo:
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);
}
}
类 FooRepository:
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);
}
}
EntityManager.lock
是JPA规范的一部分,因此JPA提供者有责任确保它按照规范工作(示例)。如果它不能(按照规范工作),那么无论如何我们作为最终用户都无能为力,直到供应商修复问题。 - manishfooRepository.lock(savedFoo)
,而不是EntityManager.lock()
,抱歉让你们感到困惑。我已经添加了//given
,//when
,//then
来展示SUT是什么。 测试的原因是我想将所有与Foo
相关的数据操作放在FooRepository
上,并且在需要时将对FooRepository
进行模拟。 - ysl