开启声明式事务

spring.xml里配置

<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource">
		<property name="driverClassName" value="${jdbc.driverClassName}" />
		<property name="url" value="${jdbc.url}" />
		<property name="username" value="${jdbc.username}" />
		<property name="password" value="${jdbc.password}" />
		<property name="maxActive">
			<value>64</value>
		</property>
		<property name="maxIdle">
			<value>64</value>
		</property>
		<property name="maxWait">
			<value>0</value>
		</property>
		<property name="validationQuery">
			<value>select 1</value>
		</property>
		<property name="testWhileIdle">
			<value>true</value>
		</property>
		<property name="minEvictableIdleTimeMillis">
			<value>20000000</value>
		</property>
		<property name="timeBetweenEvictionRunsMillis">
			<value>3600000</value>
		</property>
	</bean>

	<bean id="TxManager"
		class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
		<property name="dataSource" ref="dataSource" />
	</bean>
    <tx:annotation-driven transaction-manager="TxManager"
		proxy-target-class="true" />

默认情况下Spring对事务回滚策略的处理

在 Spring 的文档里, 可以看到这一句话: Any RuntimeException triggers rollback, and any checked Exception does not.

spring-framework-reference/html/transaction.html

可以看到, 对于检查型异常, 默认情况下是不会对事务进行回滚的

让事务进行按自己的策略进行回滚

检查型异常

如果有检查型异常, 而又要进行事务回滚, 这时可以在检查型异常里的 catch 块里, 再次抛出 RuntimeException 即可.

RuntimeException

如果有运行时异常, Spring会自动进行事务回滚.

按自己想要的异常类型来进行选择性回滚

在要进行事务的方法里, 添加以下方法级别的注解:

@Transactional(rollbackFor=Exception.class)

这时, Spring就会按指定的异常及其子类异常类型来进行事务回滚了. 如果配置了Exception.class, 那么任何Exception及其子类抛出的异常, 都会进行事务回滚.

注意, 是要抛出异常. 如果你捕获了异常的而且又没有抛出新的异常的话, 就不会进行事务回滚了.

参考资料