2014-06-28 87 views
1

我在幾張表中插入記錄,即DeptEmp。如果Dept表成功創建,那麼只需要在Emp表中插入記錄。另外,如果Emp中的任何插入失敗,那麼我想要回滾所有包含從Emp以及Dept表中回滾的事務。Spring:Propagation.REQUIRED not working

這個我試過用Propagation.REQUIRED如下圖所示:

Java文件

public void saveEmployee(Employee empl){ 
    try { 
     jdbcTemplate.update("INSERT INTO EMP VALUES(?,?,?,?,?)",empl.getEmpId(),empl.getEmpName(), 
       empl.getDeptId(),empl.getAge(),empl.getSex()); 
    } catch (DataAccessException e) { 
     e.printStackTrace(); 
    } 

} 

@Transactional(propagation=Propagation.REQUIRED) 
public void saveRecords(){ 
    saveDepartment(dept); 
    saveEmployee(empl);  
} 

的context.xml

<tx:annotation-driven transaction-manager="transactionManager" proxy-target-class="true"/> 

<bean id="transactionManager" 
    class="org.springframework.jdbc.datasource.DataSourceTransactionManager">   
    <property name="dataSource" ref="dataSource" /> 
</bean> 

問題:

即使插入Emp表失敗,Dept插入正在持續,我不想。我想回滾一切。

請建議。

+1

您正在捕捉異常... –

回答

4

問題是你的catch塊。由於異常被捕獲,tx不會回滾。

必須拋出異常:

public void saveEmployee(Employee empl){ 
    try { 
     jdbcTemplate.update("INSERT INTO EMP VALUES(?,?,?,?,?)",empl.getEmpId(),empl.getEmpName(), 
       empl.getDeptId(),empl.getAge(),empl.getSex()); 
    } catch (DataAccessException e) { 
     e.printStackTrace(); 
     throw e; 
    } 

} 

順便說一下,語義的Progation.Required只是意味着:創建一個新的TX,如果它不存在,或使用現有的,如果有tx正在運行。


按照您的評論這裏是一個建議,看看新的TX的效果:

@Transactional(propagation=Propagation.REQUIRES_NEW) 
public void saveEmployee(Employee empl){ 
    try { 
     jdbcTemplate.update("INSERT INTO EMP VALUES(?,?,?,?,?)",empl.getEmpId(),empl.getEmpName(), 
       empl.getDeptId(),empl.getAge(),empl.getSex()); 
    } catch (DataAccessException e) { 
     e.printStackTrace(); 
     throw e; 
    } 

} 

@Transactional(propagation=Propagation.REQUIRED) 
public void saveRecords(){ 
    saveDepartment(dept); 
    try{ 
     saveEmployee(empl); 
    }catch(Exception e){Logger.log("Fail to save emp !");}  
} 

的關鍵點上可看到REQUIRES_NEW的效果是捕捉周圍saveEmployee例外。如果你沒有捕獲它:異常將在另一個tx中傳播(在進入saveRecords()時啓動的異常),它也會回滾。

+0

上述解決方案奏效。僅用於測試目的,我在'saveEmployee'方法的頂部添加了@Transactional(propagation = Propagation.REQUIRES_NEW),以查看它的工作原理。我的期望是:'Dept'記錄將被保存,'Emp'記錄將不會被保存,因爲'NEW'會創建一個新的事務。但我很驚訝地看到輸出結果:「Dept」和「Emp」記錄都沒有保存。我錯過了什麼嗎?請解釋。 – user182944

+0

爲什麼在這種情況下不引發異常?是因爲我們沒有任何東西可以回滾?另外,爲什麼我的代碼片段不起作用? try塊在調用saveEmployee方法時有什麼不同?請諮詢 – user182944

+0

@ user182944看看我編輯過的編輯;-)通過這個示例代碼,我認爲即使當empl插入失敗時,您也會看到該部門將被保存 – ben75