Spring TransactionTemplate从@Transaction方法调用

时间:2015-08-11 15:43:26

标签: java spring jpa spring-data

我在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测试用例来检查一切是否正常;对于其余的测试,一切正常,这是这个特定电话链的一部分。

我想我错过了什么......

由于

1 个答案:

答案 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;
    }