我有两个可共享倒计时闩锁事务。每个事务在单独的线程中执行。我需要这样的机制来重现“脏读”的情况。第一个事务更新“目标实体”并刷新更改而不提交,然后我将线程设置为等待状态(countdownlatch)。
在第二个事务中,我获取“目标实体”并将脏字段复制到另一个实体并保存。保存操作之后,我倒计时以继续第一个事务并回滚它。
下面是事务处理方法的代码示例。第一个:
@Transactional
public void updatePrice() {
log.info("Start price updating. Thread '{}'", Thread.currentThread().getName());
Collection<Product> products = productRepository.findAll();
products.forEach(this::updatePrice);
productRepository.saveAll(products);
entityManager.flush();
log.info("Flash changes and wait for order transaction");
try {
latch.await();
} catch (InterruptedException e) {
log.error("Something wrong");
Thread.currentThread().interrupt();
}
log.error("Rollback changes");
throw new RuntimeException("Unexpected exception");
}
第二个:我有一个由事务和 Package 器服务绑定的主服务来倒计时闩锁。
Package 器:
public void doOrder(Long productId, Long amount) {
log.info("Start do order. Thread '{}'", Thread.currentThread().getName());
orderService.doOrder(productId, amount);
log.info("Order transaction committed");
latch.countDown();
log.info("Finish order process");
}
主要服务:
@Transactional
public void doOrder(Long productId, Long amount) {
Product product = productRepository.findById(productId).get();
log.info("Get product");
Order order = Order.builder().price(product.getPrice()).amount(amount).productId(new Long(productId)).build();
orderRepository.save(order);
log.info("Save order");
}
所以,在排队的时候
orderrepository.save(订单);
线被冻住了。我在日志中只看到insert语句。
但如果我去掉“订单”和“产品”之间的关系,插入内容就不会冻结。我猜在“积”和倒计时锁上有死锁。但是这个问题只发生在mysql jdbc中。如果我切换到postgresjdbc,那就没有问题了。
ps:第一个事务执行以下查询:
select * from product;
update product set price = ...
第二个执行:
select * from product where id = ...;
insert into product_order(product_id, amount, price) values (...)
暂无答案!
目前还没有任何答案,快来回答吧!