3

我必须测试使用 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);
    }
}

4

0 回答 0