我在Spring应用程序中调用了特定的流程。
我是一个存储库,我将方法sell()称为第一次调用。
@Service
@Transactional
public class ServiceRepositoryImpl implements ServiceRepository {
@Inject
private SellRepository sellRepository;
@Override
public long sell(long id)
....
....
....
Sell sell = new Sell();
...
sellRepository.save(sell);
}
和我的SellService:
@Service
public class SellRepositoryImpl implements SellRepository {
@PersistenceContext
private EntityManager entityManager;
@Inject
SellHelperRepository sellHelperRepository;
@Inject
private TransactionTemplate transactionTemplate;
@Override
public <S extends Sell> S save(S sell) throws Exception {
transactionTemplate.execute(new TransactionCallback<S>() {
@Override
public S doInTransaction(TransactionStatus status) {
try {
...
entityManager.persist(sell);
} catch (Throwable e) {
log.error("", e);
status.setRollbackOnly();
}
return vendita;
}
});
sellHelperRepository.createTickets(sell.getId());
return vendita;
}
这是我的sellHelperRepository:
@Service
@Transactional
public class SellHelperRepositoryImpl implements SellHelperRepository {
@PersistenceContext
private EntityManager entityManager;
@Override
@Async
public void createTickets(long sellID) {
Sell sell = entityManager.find(Sell.class, sellID);
try{
...
Ticket t = new Ticket();
ticketService.save(t);
}catch(Throwable e){
sell.setStatus("CANCELED");
}
}
最后我的ticketService:
@Service
@Transactional
public class TicketRepositoryImpl implements TicketRepository {
@PersistenceContext
protected EntityManager entityManager;
@Override
@Transactional(propagation = Propagation.REQUIRES_NEW)
public Biglietto save(Ticket ticket) throws Exception {
entityManager.persist(ticket);
}
问题在于,当我在SellRepositoryImpl上进行这一系列的调用时,对象卖出并不是持久的,因为我已经超出了事务模板,但应该是!因此,当我进入SellHelperRepositoryImpl并尝试搜索卖出时,它找不到它!
需要此特定结构,因为这些方法也可用于其他存储库。 我创建了许多junit测试用例来检查一切是否正常;对于其余的测试,一切正常,这是这个特定电话链的一部分。
我想我错过了什么......
由于
答案 0 :(得分:1)
你的代码的问题在于你在@Async
方法上使用createTickets
,这迫使Spring在不同的线程中使用&#34; fresh&#34;来执行它。事务,所以你需要刷新/提交在SellRepositoryImpl
类中打开的第一个事务。
所以你可以采用三种方式
@Async
方法createTickets
在DEFAULT
READ_UNCOMMITTED
更改为SellHelperRepositoryImpl
@Service
@Transactional(isolation=Isolation.READ_UNCOMMITTED)
public class SellHelperRepositoryImpl implements SellHelperRepository {
@PersistenceContext
private EntityManager entityManager;
@Override
@Async
public void createTickets(long sellID) {
Sell sell = entityManager.find(Sell.class, sellID);
try{
...
Ticket t = new Ticket();
ticketService.save(t);
}catch(Throwable e){
sell.setStatus("CANCELED");
}
}
在save(S sell)
中刷新手动管理的交易,请参阅以下代码段。
@Override
public <S extends Sell> S save(S sell) throws Exception {
transactionTemplate.execute(new TransactionCallback<S>() {
@Override
public S doInTransaction(TransactionStatus status) {
try {
...
entityManager.persist(sell);
entityManager.getTransaction().commit();
status.flush();
} catch (Throwable e) {
log.error("", e);
status.setRollbackOnly();
}
return vendita;
}
});
sellHelperRepository.createTickets(sell.getId());
return vendita;
}