2016-07-29 69 views
0

我有以下代碼:EJB 3事務回滾問題

 @TransactionAttribute(TransactionAttributeType.REQUIRES_NEW) 
     public Car prepareCar(Data data) throws CarServiceException{ 
      Car car = null; 
      try { 
      car = carManagerBean.createCar(data); 
      Driver driver = createDriver(); 
      car.setDriver(driver); 
      } catch (Exception e) { 
      LOGGER.error(e.getMessage, e); 
      context.setRollbackOnly(); 
      throw new CarServiceException(e); 
      } 
      return car; 
     } 

的問題是,如果有些問題出現在試穿部分沒有執行(例如SQLServerException)閉鎖段和CarServiceException沒有拋出。有人知道這個代碼可能是什麼問題嗎?但交易無論如何都會回滾。 它只有在移動try-catch塊來包裝方法調用時纔有效。

回答

0

請記住,如果您的catch塊本身引發異常,它將不會到達引發異常的段。請注意,根據文檔,如果交易不再有效,setRollbackOnly()可以拋出IllegalStateException。您可能想要將catch塊包裝在另一個try/catch塊中以發現該問題。

+0

它甚至不會執行catch塊的第一行:'LOGGER.error(e.getMessage,e);' – romanvintonyak

+0

這是不可能的,除非代碼實際上沒有引發異常。嘗試在try塊的末尾插入一個調試日誌條目。 –

1

您想要捕捉事務外的異常。這樣做:

@Stateless 
public class CarServiceDelegate { 

    @TransactionAttribute(TransactionAttributeType.REQUIRES_NEW) 
    public Car prepareCar(Data data) throws CarServiceException{ 
     Car car = carManagerBean.createCar(data); 
     Driver driver = createDriver(); 
     car.setDriver(driver); 
     return car; 
    } 
} 

public class CarService { 

    @EJB 
    private CarServiceDelegate carServiceDelegate; 

    public Car prepareCar(Data data) { 
     try { 
      return carServiceDelegate.prepareCar(); 
     } catch (Exception e) { 
     // You will catch it here, when the transaction is done. 
     LOGGER.error(e.getMessage, e); 
     throw new CarServiceException(e); 
     } 
    } 

} 

至於EJB異常的哪一部分授權該交易之外的異常的傳播,我會給你一個更新。在調用@Asynchronous時會發生類似的行爲(異常被抑制)。

+0

如何在發生錯誤時恢復交易? – romanvintonyak

+0

根據EJB規範,它會自動回滾,如果發生任何異常(除非它是rollback = false的applicationeexception),則事務將回滾。 – maress

+0

根據規範,默認情況下應用程序異常是rollback = false,以前的EJB規範會區分運行時和已檢查的異常。任何RuntimeException將Tx標記爲回滾,檢查的異常不會標記它,並且您需要在應用程序代碼中調用setRollbackOnly。 – wfink