1.REQUIRED(默認模式)
方法被調用時自動開啓事務,在事務範圍內使用則使用同一個事務,否則開啓新事務即業務方法需要在一個容器裏運行,如果方法運行時,已經處在一個事務中,那麼加入到這個事務,否則自己新建一個新的事務。
@Test
public void test{
addStudent();
}
@Transactional(propagation = Propagation.REQUIRED)
public void addStudent(){
String sql = "insert into student(name) values("王華")";
jdbcTemplate.execute(sql);
addTeacher();
throw new RuntimeException(); //拋異常
}
@Transactional(propagation = Propagation.REQUIRED)
public void addTeacher(){
String sql = "insert into teacher(name) values ("李亮")";
jdbcTemplate.execute(sql);
}
經測試:無論addStudent()還是addTeacher(),如果只要有一個拋出異常,則全都回滾;不拋異常,數據正常提交
2.REQUIRES_NEW
不管是否存在事務,該方法總會爲自己發起一個新的事務。如果方法已經運行在一個事務中,則原有事務掛起,新的事務被創建
@Test
public void test{
addStudent();
}
@Transactional(propagation = Propagation.REQUIRES_NEW)
public void addStudent(){
String sql = "insert into student(name) values("王華")";
jdbcTemplate.execute(sql);
addTeacher();
throw new RuntimeException(); //拋異常
}
@Transactional(propagation = Propagation.REQUIRES_NEW)
public void addTeacher(){
String sql = "insert into teacher(name) values ("李亮")";
jdbcTemplate.execute(sql);
}
經測試:學生數據不能正確提交,教師信息被正確提交。說明這兩個操作是在兩個獨立的事務中運行,並且只要方法被調用就開啓事務。
3.Supports
自身不會開啓事務,在事務範圍內則使用相同事務,否則不使用事務,即該方法在某個事務範圍內被調用,則方法成爲該事務的一部分,如果方法沒有在事務中被調用,該方法就在沒有事務的環境下執行,因爲Supports默認自身不開啓事務
@Test
public void test{
addStudent();
}
@Transactional(propagation = Propagation.SUPPORTS)
public void addStudent(){
String sql = "insert into student(name) values("王華")";
jdbcTemplate.execute(sql);
addTeacher();
throw new RuntimeException(); //拋異常
}
@Transactional(propagation = Propagation.SUPPORTS)
public void addTeacher(){
String sql = "insert into teacher(name) values ("李亮")";
jdbcTemplate.execute(sql);
}
經測試:學生數據和教師數據都被正確提交。說明這兩個操作沒有被spring管理和開啓事務,而是使用了本地事務,由於本地事務默認自動提交因此數據都提交成功,但它們使用的卻不是同一個事務,一旦出現異常將導致數據的不一致
4.NOT_SUPPORTED
聲明方法不需要事務,即如果方法沒有關聯到一個事務,容器不會爲他開啓事務,如果方法在一個事務中被調用,該事務會被掛起,調用結束後,原先的事務會恢復執行
@Test
public void test{
addStudent();
}
@Transactional(propagation = Propagation.NOT_SUPPORTED)
public void addStudent(){
String sql = "insert into student(name) values("王華")";
jdbcTemplate.execute(sql);
addTeacher();
throw new RuntimeException(); //拋異常
}
@Transactional(propagation = Propagation.NOT_SUPPORTED)
public void addTeacher(){
String sql = "insert into teacher(name) values ("李亮")";
jdbcTemplate.execute(sql);
}
經測試:學生和老師數據都正確提交。說明這兩個操作沒有被spring管理和開啓事務,而是使用了本地事務,由於本地事務默認自動提交因此數據都提交成功
@Test
public void test{
addStudent();
}
@Transactional(propagation = Propagation.REQUIRED)
public void addStudent(){
String sql = "insert into student(name) values("王華")";
jdbcTemplate.execute(sql);
addTeacher();
throw new RuntimeException(); //拋異常
}
@Transactional(propagation = Propagation.NOT_SUPPORTED)
public void addTeacher(){
String sql = "insert into teacher(name) values ("李亮")";
jdbcTemplate.execute(sql);
}
經測試:學生數據提交失敗,教師數據提交成功。說明學生操作開啓了事務,老師操作沒有開啓事務,而是使用了本地事務
5.MANDATORY
該方法只能在一個已經存在的事務中執行,業務方法不能發起自己的事務。如果在沒有事務的環境下被調用,容器拋出例外
@Test
public void test{
addStudent();
}
@Transactional(propagation = Propagation.REQUIRED)
public void addStudent(){
String sql = "insert into student(name) values("王華")";
jdbcTemplate.execute(sql);
addTeacher();
throw new RuntimeException(); //拋異常
}
經測試:代碼報錯,org.springframework.transaction.IllegalTransactionStateException: No existing transaction found for transaction marked with propagation ‘mandatory’,沒有找到事務環境
6.NEVER
該方法絕對不能在事務範圍內執行。如果在就拋例外。只有該方法沒有關聯到任何事務,才正常執行
@Test
public void test{
addStudent();
}
@Transactional(propagation = Propagation.REQUIRED)
public void addStudent(){
String sql = "insert into student(name) values("王華")";
jdbcTemplate.execute(sql);
addTeacher();
throw new RuntimeException(); //拋異常
}
@Transactional(propagation = Propagation.NEVER)
public void addTeacher(){
String sql = "insert into teacher(name) values ("李亮")";
jdbcTemplate.execute(sql);
}
經測試:代碼報錯,由於學生開啓了事務,當調用老師方法時由於其傳播特性爲never,因此報存在事務錯誤:org.springframework.transaction.IllegalTransactionStateException: Existing transaction found for transaction marked with propagation ‘never’
7.NESTED
如果一個活動的事務存在,則運行在一個嵌套的事務中。如果沒有活動事務,則按REQUIRED屬性執行。它使用了一個單獨的事務,這個事務擁有多個可以回滾的保存點。內部事務的回滾不會對外部事務造成影響。它只對DataSourceTransactionManager事務管理器起效(需要JDBC3.0以上支持)
@Test
public void test{
addStudent();
}
@Transactional(propagation = Propagation.NESTED)
public void addStudent(){
String sql = "insert into student(name) values("王華")";
jdbcTemplate.execute(sql);
addTeacher();
throw new RuntimeException(); //拋異常
}
@Transactional(propagation = Propagation.NESTED)
public void addTeacher(){
String sql = "insert into teacher(name) values ("李亮")";
jdbcTemplate.execute(sql);
}
經測試:代碼報錯,教師數據和學生數據都沒有提交成功。說明其按照REQUIRED特性運行。對於嵌套事務,大家可以模擬兩個數據源,一方的失敗不會影響另一方