15- spring编程式事务管理
15.1 常用API
PlatformTransactionManager
它是spring事务管理的接口,参考声明式事务中的介绍
TransactionDefinition
它是事务定义接口,参考声明式事务中的介绍
TransactionTemplate
#它是事务管理模版类,继承DefaultTransactionDefinition类。用于简化事务管理,事务管理由模板类定义。
1.通过调用模板类的execute()方法来自动实现事务管理
2.方法中需要传递【TransactionCallback】、或【TransactionCallbackWithoutResult】进行业务的回调处理
TransactionCallback
#通过实现该接口的“T doInTransaction(TransactionStatus status) ”方法来定义需要事务管理的操作代码
1.适合于【有返回值】的目标方法
TransactionCallbackWithoutResult
#实现TransactionCallback接口,提供“void doInTransactionWithoutResult(TransactionStatus status)”
1.适合于【不需要返回值】的目标方法
15.2 编程式事务管理模板
public void transfer(final String sourceName,final String destName, final Float money) {
// 定义事务回调接口
TransactionCallbackWithoutResult tcwr = new TransactionCallbackWithoutResult() {
@Override
protected void doInTransactionWithoutResult(TransactionStatus transactionStatus) {
// 需要事务控制的业务代码
}
};
// 编程式事务控制(通过事务模版执行)
transactionTemplate.execute(tcwr);
}
15.3 项目目录

15.4 配置bean.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd">
<!--配置包扫描dao/service-->
<context:component-scan base-package="cn.guardwhy"/>
<!--配置JdbcTemplate-->
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
<!--注入数据源对象-->
<property name="dataSource" ref="dataSource"/>
</bean>
<!--配置数据源对象-->
<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
<!--注入连接数据库的四个基本要素-->
<property name="driverClassName" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://127.0.0.1:3306/spring"/>
<property name="username" value="root"/>
<property name="password" value="root"/>
<!--数据库连接池常用属性-->
<!-- 初始化连接数量 -->
<property name="initialSize" value="6" />
<!-- 最小空闲连接数 -->
<property name="minIdle" value="3" />
<!-- 最大并发连接数(最大连接池数量) -->
<property name="maxActive" value="50" />
<!-- 配置获取连接等待超时的时间 -->
<property name="maxWait" value="60000" />
<!-- 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒 -->
<property name="timeBetweenEvictionRunsMillis" value="60000" />
</bean>
<!--spring事务管理配置步骤-->
<!--第一步:配置事务管理器-->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<!--注入数据源对象-->
<property name="dataSource" ref="dataSource"/>
</bean>
<!--配置事务管理模板-->
<bean id="transactionTemplate" class="org.springframework.transaction.support.TransactionTemplate">
<!--注入事务管理器-->
<property name="transactionManager" ref="transactionManager"/>
</bean>
</beans>
15.5 业务层
- 账户service实现类
package cn.guardwhy.service.impl;
import cn.guardwhy.dao.AccountDao;
import cn.guardwhy.domain.Account;
import cn.guardwhy.service.AccountService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.support.TransactionCallbackWithoutResult;
import org.springframework.transaction.support.TransactionTemplate;
/**
* 账户service实现类
*/
@Service("accountService")
public class AccountServiceImpl implements AccountService{
// 定义账户dao
@Autowired
private AccountDao accountDao;
// 定义事务管理模板
@Autowired
private TransactionTemplate transactionTemplate;
/**
* 根据账户id查询账户
*
* @param accountId
*/
public Account findAccountById(Integer accountId) {
return accountDao.findAccountById(accountId);
}
/**
* 转账操作:
* 参数说明:
* sourceName:转出账户
* destName:转入账户
* money:转账金额
* @param sourceName
* @param destName
* @param money
*/
public void transfer(final String sourceName, final String destName, final Float money) {
// 定义事务回调对象
TransactionCallbackWithoutResult tcwr = new TransactionCallbackWithoutResult() {
@Override
protected void doInTransactionWithoutResult(TransactionStatus transactionStatus) {
// 1.查询转出账户
Account sourceAccount = accountDao.findAccountByName(sourceName);
// 2.查询转入账户
Account destAccount = accountDao.findAccountByName(destName);
// 3.转出账户-money
sourceAccount.setMoney(sourceAccount.getMoney()-money);
// 4.转入账户+money
destAccount.setMoney(destAccount.getMoney()+money);
// 5.更新转出账户
accountDao.updateAccount(sourceAccount);
// 6.更新转入账户
accountDao.updateAccount(destAccount);
}
};
// 使用事务模板执行
transactionTemplate.execute(tcwr);
}
}
15.6 表现层
- Controller
package cn.guardwhy.controller;
import cn.guardwhy.service.AccountService;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
/**
* 账户表现层
*/
public class AccountController {
public static void main(String[] args) {
// 1.加载spring配置文件,创建spring ioc容器
ApplicationContext context = new ClassPathXmlApplicationContext("classpath:bean.xml");
// 2.获取账户service
AccountService accountService = (AccountService)context.getBean("accountService");
// 3.转账操作
accountService.transfer("curry","james",200f);
}
}