Spring的事務(wù)管理
概念
事務(wù):邏輯上的一組操作帮非,組成這組操作的各個單元断凶,要么全部成功极颓,要么全都失敗
特性:
原子性:事務(wù)不可分割
一致性:事務(wù)執(zhí)行前后數(shù)據(jù)完整性保持一致
隔離性:一個事務(wù)的執(zhí)行不因該收到其他事務(wù)的干擾
持久性:一旦事務(wù)結(jié)束巫橄,數(shù)據(jù)就持久化到數(shù)據(jù)庫
Spring提供了七種事務(wù)的傳播行為
保證了多個操作再一個事務(wù)中
PROPAGATION_REQUIRED : 默認(rèn)值,如果A中有事務(wù)似将,使用A中的事務(wù)获黔,如果A中沒有, 創(chuàng)建一個新事務(wù)
PROPAGATION_SUPPORTS:支持事務(wù)在验,如果A中有事務(wù)玷氏,使用A中的事務(wù),如果A中沒有 事務(wù)腋舌,不用事務(wù)
PROPAGATION_MANDATORY:如果A中有事務(wù)盏触,使用A中的事務(wù),如果A中沒有事務(wù)块饺,
拋出異常
保證多個操作不在同一個事務(wù)中
PROPAGATION_REQUIRES_NEW:如果A中有事務(wù)·赞辩,將A中的事務(wù)掛起(暫停),創(chuàng)建
新事務(wù)授艰,只包含自身的操作辨嗽,如果A中沒有事務(wù),創(chuàng)建一個新事務(wù)淮腾,包含自身操作
PROPAGTION_NOT_SUPPORTED:如果A中有事務(wù)糟需,將A的事務(wù)掛起,不使用事務(wù)管理
PROPAGATION_NEVER:如果A中有事務(wù)谷朝,報(bào)異常
嵌套式事務(wù)
PROPGATION_NESTED:嵌套事務(wù)洲押,如果A中有事務(wù),按照A的事務(wù)執(zhí)行圆凰,執(zhí)行完成后诅诱,
置一個保存點(diǎn),執(zhí)行B中的操作送朱,如果沒有異常娘荡,執(zhí)行通過,如果有異常驶沼,可以選擇回滾到
最初位置炮沐,也可以回滾到保存點(diǎn)
前期準(zhǔn)備(以轉(zhuǎn)賬測試為例)
1.創(chuàng)建service和Dao的接口和實(shí)現(xiàn)類
2.將service和Dao交給Spring管理
<!-- 配置Service-->
<bean id="accountService" class="com.jdbc.test1.AccountServiceImpl">
<!-- <property name="jdbcTemplate" ref="jdbcTemplate"></property> -->
<property name="dataSource" ref="dataSource"></property>
</bean>
<!-- 配置Dao -->
<bean id="accountDao" class="com.jdbc.test1.AccountDaoImpl">
</bean>
3.配置連接池
<context:property-placeholder location="classpath:jdbc.properties" />
<!-- 配置c3p0連接池 -->
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<property name="driverClass" value="${jdbc.driverClass}"></property>
<property name="jdbcUrl" value="${jdbc.url}"></property>
<property name="user" value="${jdbc.username}"></property>
<property name="password" value="${jdbc.password}"></property>
</bean>
4.在Dao層編寫方法
public class AccountDaoImpl extends JdbcDaoSupport implements AccountDao {
//繼承JdbcDaoSupport 相當(dāng)于有了JdbcTemplate實(shí)例和set方法
@Override
public void outMoney(String from, Double money) {
// TODO 自動生成的方法存根
this.getJdbcTemplate().update("update account set money = money - ?where name=?",money,from);
}
@Override
public void inMoney(String to, Double money) {
this.getJdbcTemplate().update("update account set money = money + ? where name= ?",money,to);
}
}
5.在Service層調(diào)用Dao層方法
public class AccountServiceImpl implements AccountService {
//注入Dao
private AccountDao accountDao;
public void setAccountDao(AccountDao accountDao) {
this.accountDao = accountDao;
}
@Override
public void transfer(String from, String to, Double money) {
// TODO 自動生成的方法存根
accountDao.outMoney(from, money);
accountDao.inMoney(to, money);
}
在這種情況下,如果service層中出現(xiàn)了異常回怜,比如說:
accountDao.outMoney(from, money);
int i = 1/0;
accountDao.inMoney(to, money);
會導(dǎo)致可以轉(zhuǎn)錢而無法到賬
Spring的事務(wù)管理(編程式事務(wù))
1.配置平臺事務(wù)管理器
<!-- 配置平臺事務(wù)管理器 -->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"></property>
</bean>
2.配置Spring提供的事務(wù)管理的模板類
<!-- 配置事務(wù)管理的模板類 -->
<bean id="transactionTemplate" class="org.springframework.transaction.support.TransactionTemplate">
<property name="transactionManager" ref="transactionManager"></property>
</bean>
3.在業(yè)務(wù)層注入事務(wù)管理的模板
//注入事務(wù)管理的模板
private TransactionTemplate transactionTemplate;
public void setTransactionTemplate(TransactionTemplate transactionTemplate) {
this.transactionTemplate = transactionTemplate;
}
4.在xml中的service配置里加上事務(wù)管理
<!-- 配置Service -->
<bean id="accountService" class="com.zut.jdbc.test1.AccountServiceImpl">
<property name="accountDao" ref="accountDao"></property>
<!-- 注入事務(wù)管理的模板 -->
<property name="transactionTemplate" ref="transactionTemplate"></property>
</bean>
5.在業(yè)務(wù)層里編寫事務(wù)管理的代碼
@Override
public void transfer(final String from, final String to, final Double money) {
// TODO 自動生成的方法存根
transactionTemplate.execute(new TransactionCallbackWithoutResult() {
@Override
protected void doInTransactionWithoutResult(TransactionStatus transactionStatus) {
// TODO 自動生成的方法存根
//保證以下操作在一個事務(wù)中進(jìn)行
accountDao.outMoney(from, money);
//int i=1/0;
accountDao.inMoney(to, money);
}
});
}
Spring的事務(wù)管理(聲明式事務(wù)管理)--AOP
XML方式的聲明式事務(wù)管理
1.引入AOP的開發(fā)包
2.恢復(fù)轉(zhuǎn)賬環(huán)境
3.配置平臺事務(wù)管理器
<!-- 配置事務(wù)管理器 -->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"></property>
</bean>
4.配置增強(qiáng)
<!-- 配置事務(wù)增強(qiáng) -->
<tx:advice transaction-manager="transactionManager">
<tx:attributes>
<!-- 事務(wù)管理的規(guī)則 -->
<tx:method name="save" propagation="REQUIRED"/>
<tx:method name="update" propagation="REQUIRED"/>
<tx:method name="delete" propagation="REQUIRED"/>
<tx:method name="find" read-only="true"/>
<!-- 本次采用模糊匹配的方式-->
<tx:method name="*" propagation="REQUIRED"/>
</tx:attributes>
</tx:advice>
5.AOP配置
<!-- aop配置 -->
<aop:config>
<aop:pointcut expression="execution(* com.zut.jdbc.test2.AccountServiceImpl.*(..))" id="pointcut1"/>
<aop:advisor advice-ref="txAdvice" pointcut-ref="pointcut1"/>
</aop:config>
注解方式的聲明式事務(wù)管理
1.引入AOP開發(fā)包
2.恢復(fù)轉(zhuǎn)賬環(huán)境
3.配置平臺事務(wù)管理器(同上)
4.開啟注解事務(wù)
<!-- 開啟注解事務(wù) -->
<tx:annotation-driven transaction-manager="transactionManager"/>
5.在業(yè)務(wù)層添加注解
@Transactional
即可