1.關於事物回滾在application.xml中的配置java
<!-- (事務管理)transaction manager, use JtaTransactionManager for global tx -->
<bean id="transactionManager"
class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource" />
</bean>spring
<tx:annotation-driven transaction-manager="transactionManager"/>數據庫
還有其餘的配置方法,根據我的習慣我喜歡這種方式,固然我是與mybatis結合。編程
上面這種方式官方名稱叫編程式事務,也就是使用註解的方式配置事務,想要使用註解,則必須使用<tx:annotation-driven transaction-manager="transactionManager"/>mybatis
2.怎樣使用註解?app
我在下面給出案例,測試一下:測試
@Transactional
public class Test extends BasicTest{spa
@org.junit.Test
public void testRollBack() throws CustomException{
Country country = new Country();
country.setId(184);
country.setCountrycode("B");
country.setCountryname("ABC");
try{
countryMapper.insert(country);
int i = 4/0;
}catch(RuntimeException e){
throw new CustomException("country插入失敗");
}code
}orm
測試的結果爲:不會向數據庫寫入數據,即便沒有
try{
}catch(RuntimeException e){
throw new CustomException("country插入失敗");
}
也不會向數據庫寫入數據,網上有人說什麼必須拋出RuntimeException及其子類才能發生回滾,最近,有個比我工做時間長的老師傅說,必需要throw或者try..catch才能發生回滾,都是瞎扯。至於爲何要try..catch或者throw就是想讓咱們看到這裏異常了,容易定位錯誤。
@Transactional,沒有配置參數用做默認的事務回滾
下面是幾種常見的事務類型:
1.PROPAGATION_REQUIRED
支持當前事務,若是當前沒有事務,就新建一個事務。
@org.junit.Test
@Transactional(propagation=Propagation.REQUIRED,rollbackForClassName="Exception")
public void testRollBack1() throws CustomException{
Country country = new Country();
country.setId(184);
country.setCountrycode("B");
country.setCountryname("ABC");
countryMapper.insert(country);
int i = 4/0;
}
執行結果爲:不會向數據庫寫入數據
2.PROPAGATION_SUPPORTS
支持當前事務,若是當前沒有事務,就以非事務方式執行。
@org.junit.Test
@Transactional(propagation=Propagation.SUPPORTS,rollbackForClassName="Exception")
public void testRollBack1() throws CustomException{
Country country = new Country();
country.setId(184);
country.setCountrycode("B");
country.setCountryname("ABC");
countryMapper.insert(country);
int i = 4/0;
}
測試結果是:會向數據庫寫入數據
也就是解釋了若是當前沒有事務,就以非事務方式執行
3.PROPAGATION_MANDATORY
支持當前事務,若是當前沒有事務,就拋出異常。
@org.junit.Test
@Transactional(propagation=Propagation.MANDATORY,rollbackForClassName="Exception")
public void testRollBack1() throws CustomException{
Country country = new Country();
country.setId(184);
country.setCountrycode("B");
country.setCountryname("ABC");
countryMapper.insert(country);
int i = 4/0;
}
測試結果爲:不會向數據庫寫入數據,而且發生異常
org.springframework.transaction.IllegalTransactionStateException: No existing transaction found for transaction marked with propagation 'mandatory'
at org.springframework.transaction.support.AbstractPlatformTransactionManager.getTransaction(AbstractPlatformTransactionManager.java:359)
4.PROPAGATION_REQUIRES_NEW
新建事務,若是當前存在事務,把當前事務掛起。
@org.junit.Test
@Transactional(propagation=Propagation.REQUIRES_NEW,rollbackForClassName="Exception")
public void testRollBack1() throws CustomException{
Country country = new Country();
country.setId(184);
country.setCountrycode("B");
country.setCountryname("ABC");
countryMapper.insert(country);
int i = 4/0;
}
測試結果爲:不會向數據庫寫入數據
5.PROPAGATION_NOT_SUPPORTED
以非事務方式執行操做,若是當前存在事務,就把當前事務掛起。
@org.junit.Test
@Transactional(propagation=Propagation.NOT_SUPPORTED,rollbackForClassName="Exception")
public void testRollBack1() throws CustomException{
Country country = new Country();
country.setId(184);
country.setCountrycode("B");
country.setCountryname("ABC");
countryMapper.insert(country);
int i = 4/0;
}
測試結果爲:會向數據庫寫入數據
6.PROPAGATION_NEVER
以非事務方式執行,若是當前存在事務,則拋出異常。
@org.junit.Test
@Transactional(propagation=Propagation.NEVER,rollbackForClassName="Exception")
public void testRollBack1() throws CustomException{
Country country = new Country();
country.setId(184);
country.setCountrycode("B");
country.setCountryname("ABC");
countryMapper.insert(country);
int i = 4/0;
}
測試結果爲:會向數據庫寫入數據
7.PROPAGATION_NESTED
若是當前存在事務,則在嵌套事務內執行。若是當前沒有事務,則進行與PROPAGATION_REQUIRED相似的操做。
@org.junit.Test
@Transactional(propagation=Propagation.NESTED,rollbackForClassName="Exception")
public void testRollBack1() throws CustomException{
Country country = new Country();
country.setId(184);
country.setCountrycode("B");
country.setCountryname("ABC");
countryMapper.insert(country);
int i = 4/0;
}
測試結果爲:會向數據庫寫入數據