手动编码的方式完成事务管理:需要事务管理器,它才是真正管理事务的对象。
Spring提供了事务管理的模板,也就是一个工具类,可以省写一些代码。
第一步,注册事务管理器、事务管理模板,并在业务层注入事务管理模板,基于applicationContext.xml的配置。
<!-- 业务层类 -->
<bean id="accountService" class="com.js.demo1.AccountServiceImpl">
<!-- 在业务层注入Dao -->
<property name="accountDao" ref="accountDao"></property>
<!-- 在业务层注入事务管理模板 -->
<property name="transactionTemplate" ref="transactionTemplate"></property>
</bean>
<!-- 持久层类 -->
<bean id="accountDao" class="com.js.demo1.AccountDaoImpl">
<!-- 注入连接池对象,通过连接池对象去创建JDBC模板 -->
<property name="dataSource" ref="dataSource"></property>
</bean>
<!-- 事务管理的模板 -->
<bean id="transactionTemplate" class="org.springframework.transaction.support.TransactionTemplate">
<property name="transactionManager" ref="transactionManager"></property>
</bean>
<!-- 配置事务管理器 -->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<!-- 需要注入连接池,通过连接池获得连接 -->
<property name="dataSource" ref="dataSource"></property>
</bean>
修改业务类,添加事务模板属性。
package com.js.demo1;
import org.springframework.transaction.support.TransactionTemplate;
public class AccountServiceImpl implements AccountService{
private AccountDao accountDao;
private TransactionTemplate transactionTemplate;
public void setTransactionTemplate(TransactionTemplate transactionTemplate) {
this.transactionTemplate = transactionTemplate;
}
public void setAccountDao(AccountDao accountDao) {
this.accountDao = accountDao;
}
/**
* 转账的方法
* @param from:从哪转出
* @param to:转入目标
* @param money:转账金额
*/
public void transfer(String from, String to, double money) {
accountDao.out(from, money);
accountDao.in(to, money);
}
}
第二步:修改业务类,编写事务。
package com.js.demo1;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.support.TransactionCallbackWithoutResult;
import org.springframework.transaction.support.TransactionTemplate;
public class AccountServiceImpl implements AccountService{
private AccountDao accountDao;
private TransactionTemplate transactionTemplate;
public void setTransactionTemplate(TransactionTemplate transactionTemplate) {
this.transactionTemplate = transactionTemplate;
}
public void setAccountDao(AccountDao accountDao) {
this.accountDao = accountDao;
}
/**
* 转账的方法
* @param from:从哪转出
* @param to:转入目标
* @param money:转账金额
*/
public void transfer(final String from, final String to,final double money) {
transactionTemplate.execute(new TransactionCallbackWithoutResult() {
@Override
protected void doInTransactionWithoutResult(TransactionStatus status) {
accountDao.out(from, money);
accountDao.in(to, money);
}
});
}
}
第三步:进行测试。
转账成功。
第四步:测试有异常发生的情况下,事务的管理是否生效。
修改业务类:
public void transfer(final String from, final String to,final double money) {
transactionTemplate.execute(new TransactionCallbackWithoutResult() {
@Override
protected void doInTransactionWithoutResult(TransactionStatus status) {
accountDao.out(from, money);
int d = 1/0;
accountDao.in(to, money);
}
});
}
第五步:运行测试。
金额没有发生变化,说明事务管理成功。
这就是使用手动编码的方式来实现事务的管理。
手动编码方式的缺点:代码量增加,代码有侵入性。业务层代码中嵌入了dao代码。