手动编码的方式完成事务管理:需要事务管理器,它才是真正管理事务的对象。
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代码。