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;
}
测试结果为:会向数据库写入数据