《Spring - 事務管理(一)基本概念》
1. 使用TransactionTemplate手動提交事務
spring配置
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource ">
<property name="url" value="${jdbc.url}"></property>
<property name="driverClassName" value="${jdbc.driver}"></property>
<property name="username" value="${jdbc.username}"></property>
<property name="password" value="${jdbc.password}"></property>
</bean>
<!-- 配置事務管理器 -->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<!-- 注入連接池對象 -->
<property name="dataSource" ref="dataSource"></property>
</bean>
<!-- 配置事務管理的模板:Spring爲了簡化事務管理的代碼而提供的類 -->
<bean id="transactionTemplate" class="org.springframework.transaction.support.TransactionTemplate">
<property name="transactionManager" ref="transactionManager"></property>
</bean>
業務代碼
@Autowired
private TransactionTemplate transactionTemplate;
@Override
public void xxx(...) {
transactionTemplate.execute(new TransactionCallbackWithoutResult() {
@Override
protected void doInTransactionWithoutResult(TransactionStatus arg0) {
//TODO 實現業務
}
});
}
2. 使用TransactionProxyFactoryBean代理提交事務
spring配置
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource ">
<property name="url" value="${jdbc.url}"></property>
<property name="driverClassName" value="${jdbc.driver}"></property>
<property name="username" value="${jdbc.username}"></property>
<property name="password" value="${jdbc.password}"></property>
</bean>
<!-- 配置事務管理器 -->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<!-- 注入連接池對象 -->
<property name="dataSource" ref="dataSource"></property>
</bean>
<!-- 配置業務層的代理 -->
<bean id="accountServiceProxy"
class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
<!-- 配置目標對象 -->
<property name="target" ref="accountService"/>
<!-- 注入事務管理器 -->
<property name="transactionManager" ref="transactionManager"/>
<!-- 注入事務屬性 -->
<property name="transactionAttributes">
<props>
<!-- prop格式:
* PROPAGATION :事務的傳播行爲。
* ISOLATION :事務的隔離級別。
* readOnly :只讀。
* -Exception :發生哪些異常回滾事務。
* +Exception :發生哪些異常事務不會滾。 -->
<prop key="transfer*">PROPAGATION_REQUIRED</prop>
</props>
</property>
</bean>
業務代碼
@Override
public void xxx(...) {
//TODO 實現業務
}
功能代碼
//使用代理
@Resource(name = "accountServiceProxy")
private AccountService accountService;
3. 使用AOP配置事務(常用)
spring配置
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource ">
<property name="url" value="${jdbc.url}"></property>
<property name="driverClassName" value="${jdbc.driver}"></property>
<property name="username" value="${jdbc.username}"></property>
<property name="password" value="${jdbc.password}"></property>
</bean>
<!-- 配置事務管理器 -->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<!-- 注入連接池對象 -->
<property name="dataSource" ref="dataSource"></property>
</bean>
<!-- 配置事務的通知:(事務的增強) -->
<tx:advice id="txAdvice" transaction-manager="transactionManager">
<tx:attributes>
<!--
propagation :事務傳播行爲
isolation :事務隔離級別
read-only :只讀
rollback-for:發生哪些異常回滾
no-rollback-for:發生哪些異常不回滾
timeout :過期信息
-->
<tx:method name="transfer*" propagation="REQUIRED"/>
<tx:method name="add*" propagation="REQUIRED" isolation="READ_COMMITTED"
rollback-for="java.lang.Exception"/>
</tx:attributes>
</tx:advice>
<!-- 配置切面 -->
<aop:config>
<!-- 配置切入點 -->
<!-- 第一個*:任意返回值,+:AccountService所有子類,*任意的方法,(..)任意的參數 -->
<aop:pointcut id="pointcut1" expression="execution(* com.test.spring.demo3.AccountService+.*(..))" />
<aop:pointcut id="pcut" expression="execution(* com.*.service.*.*.*(..))"/>
<!-- 切面 -->
<!-- advisor只配置1個切點,aspect配置多切點 -->
<aop:advisor advice-ref="txAdvice" pointcut-ref="pointcut1"/>
<aop:advisor advice-ref="txAdvice" pointcut-ref="pcut"/>
</aop:config>
<!-- 註解掃描 -->
<context:component-scan base-package="com.test.spring"/>
業務代碼
@Override
public void xxx(...) {
//TODO 實現業務
}
功能代碼
@Autowired
private AccountService accountService;
4. 註解方式(常用)
spring配置
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource ">
<property name="url" value="${jdbc.url}"></property>
<property name="driverClassName" value="${jdbc.driver}"></property>
<property name="username" value="${jdbc.username}"></property>
<property name="password" value="${jdbc.password}"></property>
</bean>
<!-- 配置事務管理器 -->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<!-- 注入連接池對象 -->
<property name="dataSource" ref="dataSource"></property>
</bean>
<!-- 註解掃描 -->
<context:component-scan base-package="com.test.spring.demo4"/>
<!-- 開啓註解事務 -->
<tx:annotation-driven transaction-manager="transactionManager"/>
業務代碼
@Transactional(propagation = Propagation.REQUIRED)
public class XxxServiceImpl implements XxxService {
@Autowired
private XxxDao xxxDao;
@Override
public void xxx(...) {
//TODO 實現業務
}
}
功能代碼
@Autowired
private XxxService xxxtService;
案例代碼
gitee地址