2017-03-07 18 views
2

我不確定爲什麼以下方法無效。我希望新的事務以循環開始(propagation = REQUIRES_NEW)。在此循環中觸發新事務之前,每個事務都應該被提交。但是,只有循環的第一次迭代纔會執行,然後什麼都不會發生。在循環中傳播新事務(使用REQUIRES_NEW)未按預期工作

@Service 
    @Transactional 
    public class Aimpl implements A { 

    @Autowired 
    private B b; 

    private Logger logger = LoggerFactory.getLogger(this.getClass()); 

     public void methodA(List<Customer> customers){ 
     logger.info("before loop"); //gets printed 
     customers.forEach(customer -> { 
     logger.info("1"); //--> this gets printed 
     b.processEachCustomer(customer); 
     logger.info("2"); //- this does not get printed 
     }); 
     logger.info("after loop"); //does not get printed 
     } 
    } 

//-----------------Second class---------- 


@Service 
    @Transactional 
    public class Bimpl implements B { 

    @Autowired 
    private MyRepository repository; 

    private Logger logger = LoggerFactory.getLogger(this.getClass()); 

     @Transactional(propagation = Propagation.REQUIRES_NEW) 
     public void processEachCustomer(Customer customer){ 

     //process each customer - a new transaction everytime 
     //and it should be committed independently 
     repository.updateCustomerData(customer.getId()); 
     logger.info("3");//this does not get printed 
     } 
    } 

這是我的存儲庫類,只是在表中爲一行發佈更新查詢。

public interface MyRepository extends Repository<Customer , Long> { 

    @Modifying 
    @Query("UPDATE Customer c SET c.status = 1 WHERE i.id= :id") 
    int setStatusById(@Param("id") Integer id); 

} 

我在做什麼錯在這裏?基本上,爲什麼只有循環的第一次迭代起作用,其餘的則不起作用?我試圖調試它,並且在第一次迭代之後沒有看到應用程序在斷點處停止。

+0

你是什麼意思'那麼它幾乎停止執行'? – galovics

+0

第一次迭代後沒有任何反應。我試圖調試它,它永遠不會停在斷點處,並且沒有日誌消息表明發生任何事情 – Righto

+0

如果在循環內部和循環之前/之後放置日誌消息會怎樣?什麼是寫入控制檯? – galovics

回答

0

當我從methodA()中移除註釋並刪除類Aimpl中的類級別事務註釋時,此工作正常。

@Service 
    public class Aimpl implements A { 

    @Autowired 
    private B b; 

    private Logger logger = LoggerFactory.getLogger(this.getClass()); 

     public void methodA(List<Customer> customers){ 
     customers.forEach(customer -> { 
     b.processEachCustomer(customer); 
     }); 
     } 
    } 

// -----------------二等----------

@Service 
@Transactional 
public class Bimpl implements B { 

@Autowired 
private MyRepository repository; 

private Logger logger = LoggerFactory.getLogger(this.getClass()); 

    @Transactional(propagation = Propagation.REQUIRES_NEW) 
    public void processEachCustomer(Customer customer){ 

    //process each customer - a new transaction everytime 
    //and it should be committed independently 
    repository.updateCustomerData(customer.getId()); 
    } 
} 

編輯2:讓我在這裏糾正自己。即使我沒有從方法中移除事務註釋,並且讓該類保持註釋爲事務性,這也可以正常工作。這裏真正的問題是由於其他進程獲取鎖而導致數據庫級發生死鎖。代碼是正確的。

0

方法A將創建具有默認範圍的事務REQUIRED,因爲@Transactional處於類級別。

+0

即使我更新methodA並將其註釋爲@Transactional(propagation = Propagation.REQUIRES_NEW) - 問題仍然相同 – Righto

+0

這不應該是接受的答案,OP期望方法B產生新的事務這與調用者事務完全無關(在執行內部事務時外部事務被掛起)。 – Gab

+0

好的,我應該接受我的答案 – Righto