我必须测试使用 Micronaut 数据和 Hibernate 完成的悲观锁实现。当我运行 JUnit 测试用例时,使用命令gradle test
它给出错误
io.micronaut.context.exceptions.BeanInstantiationException: Error instantiating bean of type [org.hibernate.Session]: Could not obtain transaction-synchronized Session for current thread
但是当在控制器的上下文中调用时,函数 (orgAccountRepository.findTop1ByStatus) 会按预期工作。
更奇怪的是,当使用 vs code java test runner 执行时,测试运行成功。
这个测试是为了验证表行上的悲观写锁是否工作。所以本质上我必须创建多个并发事务来竞争获取锁,然后验证锁定机制是否正常工作。
有人可以就使用 JUnit 定义事务提供任何建议。
@Repository
public abstract class OrgAccountRepository implements CrudRepository<OrgAccount, String> {
private final EntityManager entityManager;
public OrgAccountRepository(EntityManager entityManager) {
this.entityManager = entityManager;
}
public Optional<OrgAccount> findTop1ByStatus(OrgAccountStatusName name) {
// Lock the result rows with PESSIMISTIC_WRITE lock
List<OrgAccount> orgAccounts = entityManager
.createQuery("FROM OrgAccount AS oa WHERE oa.status = :status", OrgAccount.class)
.setLockMode(LockModeType.PESSIMISTIC_WRITE).setParameter("status", name)
.getResultList();
if (orgAccounts.size() > 0) {
return Optional.ofNullable(orgAccounts.get(0));
}
return Optional.ofNullable(null);
}
}
@MicronautTest(environments = {"test"})
public class LockTableTest {
@Inject
LockTableHelper lockTableHelper;
@Test
void test() {
Thread t1 = new Thread() {
public void run() {
lockTableHelper.testRun();
}
};
t1.start();
//<Thread join and other logics>
....
....
}
}
}
public class LockTableHelper {
private final Logger log = LoggerFactory.getLogger(LockTableHelper.class);
@Inject
OrgAccountRepository orgAccountRepository;
@Transactional
public void testRun() {
Optional<OrgAccount> account =
orgAccountRepository.findTop1ByStatus(OrgAccountStatusName.UNASSIGNED);
}
}