此接口是 Spring 的事务管理器,提供了如下方法:
我们在实际开发中都是使用它的实现类
此接口是事务的定义信息对象,提供了如下方法:
事务的隔离级别
事务的传播行为
事务的超时时间
默认值是-1,没有超时限制。如果有,以秒为单位进行设置
是否是只读事务
读写型事务配置(一般用于增删改方法)
只读型事务配置(一般用于查询方法)
导入依赖
<dependencies>
<dependency>
<groupId>org.springframeworkgroupId>
<artifactId>spring-contextartifactId>
<version>5.0.2.RELEASEversion>
dependency>
<dependency>
<groupId>org.springframeworkgroupId>
<artifactId>spring-jdbcartifactId>
<version>5.0.2.RELEASEversion>
dependency>
<dependency>
<groupId>org.springframeworkgroupId>
<artifactId>spring-txartifactId>
<version>5.0.2.RELEASEversion>
dependency>
<dependency>
<groupId>mysqlgroupId>
<artifactId>mysql-connector-javaartifactId>
<version>5.1.32version>
dependency>
<dependency>
<groupId>org.aspectjgroupId>
<artifactId>aspectjweaverartifactId>
<version>1.8.13version>
dependency>
<dependency>
<groupId>junitgroupId>
<artifactId>junitartifactId>
<version>4.12version>
dependency>
<dependency>
<groupId>org.springframeworkgroupId>
<artifactId>spring-testartifactId>
<version>5.0.2.RELEASEversion>
dependency>
<dependency>
<groupId>com.alibabagroupId>
<artifactId>druidartifactId>
<version>1.0.9version>
dependency>
dependencies>
准备数据库和表
create table account(
id int primary key auto_increment,
name varchar(40),
money double
)character set utf8 collate utf8_general_ci;
账户实体类
/**
* 账户实体类
*/
public class Account implements Serializable {
private Integer id;
private String name;
private Double money;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Double getMoney() {
return money;
}
public void setMoney(Double money) {
this.money = money;
}
@Override
public String toString() {
return "Account{" +
"id=" + id +
", name='" + name + '\'' +
", money=" + money +
'}';
}
}
编写业务层接口和实现类
AccountService 接口
/**
* 账户的业务层接口
*/
public interface AccountService {
/**
* 查询所有
* @return
*/
List<Account> findAllAccount();
/**
* 查询一个
* @param id
* @return
*/
Account findAccountById(Integer id);
/**
* 保存操作
* @param account
*/
void saveAccount(Account account);
/**
* 更新操作
* @param account
*/
void updateAccount(Account account);
/**
* 删除操作
* @param id
*/
void deleteAccount(Integer id);
/**
* 转账操作
* @param sourceName 转出账户
* @param targetName 转入账户
* @param money 转账金额
*/
void transfer(String sourceName, String targetName, double money);
}
AccountServiceImpl_OLD
/**
* 账户业务层实现类
*/
public class AccountServiceImpl_OLD implements AccountService {
private AccountDao accountDao;
public void setAccountDao(AccountDao accountDao) {
this.accountDao = accountDao;
}
public List<Account> findAllAccount() {
return accountDao.findAllAccount();
}
public Account findAccountById(Integer id) {
return accountDao.findAccountById(id);
}
public void saveAccount(Account account) {
accountDao.saveAccount(account);
}
public void updateAccount(Account account) {
accountDao.updateAccount(account);
}
public void deleteAccount(Integer id) {
accountDao.deleteAccount(id);
}
public void transfer(String sourceName, String targetName, double money) {
// 2.1 查询两个账户信息
Account source = accountDao.findAccountByName(sourceName);
Account target = accountDao.findAccountByName(targetName);
// 2.2 转出账户减钱,转入帐户加钱
source.setMoney(source.getMoney() - money);
target.setMoney(target.getMoney() + money);
// 2.3 更新操作
accountDao.updateAccount(source);
// 2.4 模拟转账异常
int i = 3 / 0;
accountDao.updateAccount(target);
}
}
编写 DAO 接口和实现类
AccountDao 接口
/**
* 账户的持久层接口
*/
public interface AccountDao {
/**
* 查询所有
* @return
*/
List<Account> findAllAccount();
/**
* 查询一个
* @param id
* @return
*/
Account findAccountById(Integer id);
/**
* 根据名称查询账户
* @param accountName
* @return
*/
Account findAccountByName(String accountName);
/**
* 保存操作
* @param account
*/
void saveAccount(Account account);
/**
* 更新操作
* @param account
*/
void updateAccount(Account account);
/**
* 删除操作
* @param id
*/
void deleteAccount(Integer id);
}
AccountDaoImpl
/**
* 账户的持久层实现类
*/
public class AccountDaoImpl implements AccountDao {
private JdbcTemplate jdbcTemplate;
public void setJdbcTemplate(JdbcTemplate jdbcTemplate) {
this.jdbcTemplate = jdbcTemplate;
}
public List<Account> findAllAccount() {
String sql = "select * from account";
List<Account> accounts = jdbcTemplate.query(sql, new BeanPropertyRowMapper<Account>(Account.class));
return accounts;
}
public Account findAccountById(Integer id) {
String sql = "select * from account where id = ?";
Account account = jdbcTemplate.queryForObject(sql, new BeanPropertyRowMapper<Account>(Account.class), id);
return account;
}
public Account findAccountByName(String accountName) {
String sql = "select * from account where name = ?";
Account account = jdbcTemplate.queryForObject(sql, new BeanPropertyRowMapper<Account>(Account.class), accountName);
return account;
}
public void saveAccount(Account account) {
String sql = "insert into account values(null,?,?)";
jdbcTemplate.update(sql, account.getName(), account.getMoney());
}
public void updateAccount(Account account) {
String sql = "update account set name = ? , money = ? where id = ?";
jdbcTemplate.update(sql, account.getName(), account.getMoney(), account.getId());
}
public void deleteAccount(Integer id) {
String sql = "delete from account where id = ?";
jdbcTemplate.update(sql,id);
}
}
配置文件
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd">
<bean id="accountService_OLD" class="com.zt.service.impl.AccountServiceImpl_OLD">
<property name="accountDao" ref="accountDao">property>
bean>
<bean id="accountDao" class="com.zt.dao.impl.AccountDaoImpl">
<property name="jdbcTemplate" ref="jdbcTemplate">property>
bean>
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate" scope="prototype" >
<property name="dataSource" ref="dataSource">property>
bean>
<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver">property>
<property name="url" value="jdbc:mysql://127.0.0.1:3306/spring_day02">property>
<property name="username" value="root">property>
<property name="password" value="123456">property>
<property name="initialSize" value="5">property>
<property name="maxActive" value="10">property>
<property name="maxWait" value="3000">property>
bean>
beans>
配置事务管理器
使用 bean 标签配置事务管理器,并传入一个数据源
配置事务的通知
使用 tx:advice 标签配置事务通知
配置 AOP,配置通用切入点表达式
建立事务通知和切入点表达式的对应关系
配置事务的属性
是在事务的通知 tx:advice 标签的内部
<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>
<tx:method name="*" propagation="REQUIRED" read-only="false">tx:method>
<tx:method name="find*" propagation="SUPPORTS" read-only="true">tx:method>
tx:attributes>
tx:advice>
<aop:config>
<aop:pointcut id="pt1" expression="execution(* com.zt.service.impl.*.*(..))">aop:pointcut>
<aop:advisor advice-ref="txAdvice" pointcut-ref="pt1">aop:advisor>
aop:config>
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations= {"classpath:bean.xml"})
public class AccountService_OLDTest {
@Autowired
private AccountService accountService;
@Test
public void testTransfer(){
accountService.transfer("aaa","bbb",500);
}
}
导入依赖
<dependencies>
<dependency>
<groupId>org.springframeworkgroupId>
<artifactId>spring-contextartifactId>
<version>5.0.2.RELEASEversion>
dependency>
<dependency>
<groupId>org.springframeworkgroupId>
<artifactId>spring-jdbcartifactId>
<version>5.0.2.RELEASEversion>
dependency>
<dependency>
<groupId>org.springframeworkgroupId>
<artifactId>spring-txartifactId>
<version>5.0.2.RELEASEversion>
dependency>
<dependency>
<groupId>mysqlgroupId>
<artifactId>mysql-connector-javaartifactId>
<version>5.1.32version>
dependency>
<dependency>
<groupId>org.aspectjgroupId>
<artifactId>aspectjweaverartifactId>
<version>1.8.13version>
dependency>
<dependency>
<groupId>junitgroupId>
<artifactId>junitartifactId>
<version>4.12version>
dependency>
<dependency>
<groupId>org.springframeworkgroupId>
<artifactId>spring-testartifactId>
<version>5.0.2.RELEASEversion>
dependency>
<dependency>
<groupId>com.alibabagroupId>
<artifactId>druidartifactId>
<version>1.0.9version>
dependency>
dependencies>
准备数据库和表
create table account(
id int primary key auto_increment,
name varchar(40),
money double
)character set utf8 collate utf8_general_ci;
账户实体类
/**
* 账户实体类
*/
public class Account implements Serializable {
private Integer id;
private String name;
private Double money;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Double getMoney() {
return money;
}
public void setMoney(Double money) {
this.money = money;
}
@Override
public String toString() {
return "Account{" +
"id=" + id +
", name='" + name + '\'' +
", money=" + money +
'}';
}
}
编写业务层接口和实现类
AccountService 接口
/**
* 账户的业务层接口
*/
public interface AccountService {
/**
* 查询所有
* @return
*/
List<Account> findAllAccount();
/**
* 查询一个
* @param id
* @return
*/
Account findAccountById(Integer id);
/**
* 保存操作
* @param account
*/
void saveAccount(Account account);
/**
* 更新操作
* @param account
*/
void updateAccount(Account account);
/**
* 删除操作
* @param id
*/
void deleteAccount(Integer id);
/**
* 转账操作
* @param sourceName 转出账户
* @param targetName 转入账户
* @param money 转账金额
*/
void transfer(String sourceName, String targetName, double money);
}
AccountServiceImpl_OLD
/**
* 账户业务层实现类
*/
@Service("accountService")
public class AccountServiceImpl_OLD implements AccountService {
@Autowired
private AccountDao accountDao;
public List<Account> findAllAccount() {
return accountDao.findAllAccount();
}
public Account findAccountById(Integer id) {
return accountDao.findAccountById(id);
}
public void saveAccount(Account account) {
accountDao.saveAccount(account);
}
public void updateAccount(Account account) {
accountDao.updateAccount(account);
}
public void deleteAccount(Integer id) {
accountDao.deleteAccount(id);
}
public void transfer(String sourceName, String targetName, double money) {
// 2.1 查询两个账户信息
Account source = accountDao.findAccountByName(sourceName);
Account target = accountDao.findAccountByName(targetName);
// 2.2 转出账户减钱,转入帐户加钱
source.setMoney(source.getMoney() - money);
target.setMoney(target.getMoney() + money);
// 2.3 更新操作
accountDao.updateAccount(source);
// 2.4 模拟转账异常
// int i = 3 / 0;
accountDao.updateAccount(target);
}
}
编写 DAO 接口和实现类
AccountDao 接口
/**
* 账户的持久层接口
*/
public interface AccountDao {
/**
* 查询所有
* @return
*/
List<Account> findAllAccount();
/**
* 查询一个
* @param id
* @return
*/
Account findAccountById(Integer id);
/**
* 根据名称查询账户
* @param accountName
* @return
*/
Account findAccountByName(String accountName);
/**
* 保存操作
* @param account
*/
void saveAccount(Account account);
/**
* 更新操作
* @param account
*/
void updateAccount(Account account);
/**
* 删除操作
* @param id
*/
void deleteAccount(Integer id);
}
AccountDaoImpl
/**
* 账户的持久层实现类
*/
@Repository("accountDao")
public class AccountDaoImpl implements AccountDao {
@Autowired
private JdbcTemplate jdbcTemplate;
public List<Account> findAllAccount() {
String sql = "select * from account";
List<Account> accounts = jdbcTemplate.query(sql, new BeanPropertyRowMapper<Account>(Account.class));
return accounts;
}
public Account findAccountById(Integer id) {
String sql = "select * from account where id = ?";
Account account = jdbcTemplate.queryForObject(sql, new BeanPropertyRowMapper<Account>(Account.class), id);
return account;
}
public Account findAccountByName(String accountName) {
String sql = "select * from account where name = ?";
Account account = jdbcTemplate.queryForObject(sql, new BeanPropertyRowMapper<Account>(Account.class), accountName);
return account;
}
public void saveAccount(Account account) {
String sql = "insert into account values(null,?,?)";
jdbcTemplate.update(sql, account.getName(), account.getMoney());
}
public void updateAccount(Account account) {
String sql = "update account set name = ? , money = ? where id = ?";
jdbcTemplate.update(sql, account.getName(), account.getMoney(), account.getId());
}
public void deleteAccount(Integer id) {
String sql = "delete from account where id = ?";
jdbcTemplate.update(sql,id);
}
}
配置文件
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
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/tx
http://www.springframework.org/schema/tx/spring-tx.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd">
<context:component-scan base-package="com.zt">context:component-scan>
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate" scope="prototype" >
<property name="dataSource" ref="dataSource">property>
bean>
<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver">property>
<property name="url" value="jdbc:mysql://127.0.0.1:3306/spring_day02">property>
<property name="username" value="root">property>
<property name="password" value="123456">property>
<property name="initialSize" value="5">property>
<property name="maxActive" value="10">property>
<property name="maxWait" value="3000">property>
bean>
beans>
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource">property>
bean>
<tx:annotation-driven transaction-manager="transactionManager">tx:annotation-driven>
/**
* 账户业务层实现类
*/
@Service("accountService")
@Transactional(propagation = Propagation.REQUIRED, readOnly = false)
public class AccountServiceImpl_OLD implements AccountService {
@Autowired
private AccountDao accountDao;
@Transactional(propagation = Propagation.SUPPORTS, readOnly = true)
public List<Account> findAllAccount() {
return accountDao.findAllAccount();
}
@Transactional(propagation = Propagation.SUPPORTS, readOnly = true)
public Account findAccountById(Integer id) {
return accountDao.findAccountById(id);
}
public void saveAccount(Account account) {
accountDao.saveAccount(account);
}
public void updateAccount(Account account) {
accountDao.updateAccount(account);
}
public void deleteAccount(Integer id) {
accountDao.deleteAccount(id);
}
public void transfer(String sourceName, String targetName, double money) {
// 2.1 查询两个账户信息
Account source = accountDao.findAccountByName(sourceName);
Account target = accountDao.findAccountByName(targetName);
// 2.2 转出账户减钱,转入帐户加钱
source.setMoney(source.getMoney() - money);
target.setMoney(target.getMoney() + money);
// 2.3 更新操作
accountDao.updateAccount(source);
// 2.4 模拟转账异常
// int i = 3 / 0;
accountDao.updateAccount(target);
}
}
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations= {"classpath:bean.xml"})
public class AccountService_OLDTest {
@Autowired
private AccountService accountService;
@Test
public void testTransfer(){
accountService.transfer("aaa","bbb",500);
}
}
导入依赖
<dependencies>
<dependency>
<groupId>org.springframeworkgroupId>
<artifactId>spring-contextartifactId>
<version>5.0.2.RELEASEversion>
dependency>
<dependency>
<groupId>org.springframeworkgroupId>
<artifactId>spring-jdbcartifactId>
<version>5.0.2.RELEASEversion>
dependency>
<dependency>
<groupId>org.springframeworkgroupId>
<artifactId>spring-txartifactId>
<version>5.0.2.RELEASEversion>
dependency>
<dependency>
<groupId>mysqlgroupId>
<artifactId>mysql-connector-javaartifactId>
<version>5.1.32version>
dependency>
<dependency>
<groupId>org.aspectjgroupId>
<artifactId>aspectjweaverartifactId>
<version>1.8.13version>
dependency>
<dependency>
<groupId>junitgroupId>
<artifactId>junitartifactId>
<version>4.12version>
dependency>
<dependency>
<groupId>org.springframeworkgroupId>
<artifactId>spring-testartifactId>
<version>5.0.2.RELEASEversion>
dependency>
<dependency>
<groupId>com.alibabagroupId>
<artifactId>druidartifactId>
<version>1.0.9version>
dependency>
dependencies>
准备数据库和表
create table account(
id int primary key auto_increment,
name varchar(40),
money double
)character set utf8 collate utf8_general_ci;
账户实体类
/**
* 账户实体类
*/
public class Account implements Serializable {
private Integer id;
private String name;
private Double money;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Double getMoney() {
return money;
}
public void setMoney(Double money) {
this.money = money;
}
@Override
public String toString() {
return "Account{" +
"id=" + id +
", name='" + name + '\'' +
", money=" + money +
'}';
}
}
编写业务层接口和实现类
AccountService 接口
/**
* 账户的业务层接口
*/
public interface AccountService {
/**
* 查询所有
* @return
*/
List<Account> findAllAccount();
/**
* 查询一个
* @param id
* @return
*/
Account findAccountById(Integer id);
/**
* 保存操作
* @param account
*/
void saveAccount(Account account);
/**
* 更新操作
* @param account
*/
void updateAccount(Account account);
/**
* 删除操作
* @param id
*/
void deleteAccount(Integer id);
/**
* 转账操作
* @param sourceName 转出账户
* @param targetName 转入账户
* @param money 转账金额
*/
void transfer(String sourceName, String targetName, double money);
}
AccountServiceImpl_OLD
/**
* 账户业务层实现类
*/
@Service("accountService")
public class AccountServiceImpl_OLD implements AccountService {
@Autowired
private AccountDao accountDao;
public List<Account> findAllAccount() {
return accountDao.findAllAccount();
}
public Account findAccountById(Integer id) {
return accountDao.findAccountById(id);
}
public void saveAccount(Account account) {
accountDao.saveAccount(account);
}
public void updateAccount(Account account) {
accountDao.updateAccount(account);
}
public void deleteAccount(Integer id) {
accountDao.deleteAccount(id);
}
public void transfer(String sourceName, String targetName, double money) {
// 2.1 查询两个账户信息
Account source = accountDao.findAccountByName(sourceName);
Account target = accountDao.findAccountByName(targetName);
// 2.2 转出账户减钱,转入帐户加钱
source.setMoney(source.getMoney() - money);
target.setMoney(target.getMoney() + money);
// 2.3 更新操作
accountDao.updateAccount(source);
// 2.4 模拟转账异常
// int i = 3 / 0;
accountDao.updateAccount(target);
}
}
编写 DAO 接口和实现类
AccountDao 接口
/**
* 账户的持久层接口
*/
public interface AccountDao {
/**
* 查询所有
* @return
*/
List<Account> findAllAccount();
/**
* 查询一个
* @param id
* @return
*/
Account findAccountById(Integer id);
/**
* 根据名称查询账户
* @param accountName
* @return
*/
Account findAccountByName(String accountName);
/**
* 保存操作
* @param account
*/
void saveAccount(Account account);
/**
* 更新操作
* @param account
*/
void updateAccount(Account account);
/**
* 删除操作
* @param id
*/
void deleteAccount(Integer id);
}
AccountDaoImpl
/**
* 账户的持久层实现类
*/
@Repository("accountDao")
public class AccountDaoImpl implements AccountDao {
@Autowired
private JdbcTemplate jdbcTemplate;
public List<Account> findAllAccount() {
String sql = "select * from account";
List<Account> accounts = jdbcTemplate.query(sql, new BeanPropertyRowMapper<Account>(Account.class));
return accounts;
}
public Account findAccountById(Integer id) {
String sql = "select * from account where id = ?";
Account account = jdbcTemplate.queryForObject(sql, new BeanPropertyRowMapper<Account>(Account.class), id);
return account;
}
public Account findAccountByName(String accountName) {
String sql = "select * from account where name = ?";
Account account = jdbcTemplate.queryForObject(sql, new BeanPropertyRowMapper<Account>(Account.class), accountName);
return account;
}
public void saveAccount(Account account) {
String sql = "insert into account values(null,?,?)";
jdbcTemplate.update(sql, account.getName(), account.getMoney());
}
public void updateAccount(Account account) {
String sql = "update account set name = ? , money = ? where id = ?";
jdbcTemplate.update(sql, account.getName(), account.getMoney(), account.getId());
}
public void deleteAccount(Integer id) {
String sql = "delete from account where id = ?";
jdbcTemplate.update(sql,id);
}
}
在 java 包下创建 config 包
创建 SpringConfiguration
/**
* spring 的配置类,相当于 bean.xml
*/
@Configuration
@ComponentScan("com.zt")
@Import({JdbcConfig.class})
@PropertySource("druid.properties")
public class SpringConfiguration {
}
创建 JdbcConfig
/**
* 连接数据库相关的配置类
*/
public class JdbcConfig {
@Value("${driverClassName}")
private String driverClassName;
@Value("${url}")
private String url;
@Value("${name}")
private String name;
@Value("${password}")
private String password;
@Value("${initialSize}")
private int initialSize;
@Value("${maxActive}")
private int maxActive;
@Value("${maxWait}")
private int maxWait;
@Bean("jdbcTemplate")
@Scope("prototype")
public JdbcTemplate createJdbcTemplate(DataSource dataSource){
return new JdbcTemplate(dataSource);
}
@Bean("dataSource")
public DataSource createDataSource(){
DruidDataSource druidDataSource = new DruidDataSource();
druidDataSource.setDriverClassName(driverClassName);
druidDataSource.setUrl(url);
druidDataSource.setUsername(name);
druidDataSource.setPassword(password);
druidDataSource.setInitialSize(initialSize);
druidDataSource.setMaxActive(maxActive);
druidDataSource.setMaxWait(maxWait);
return druidDataSource;
}
}
在 resouces 创建 druid.properties
driverClassName=com.mysql.jdbc.Driver
url=jdbc:mysql://127.0.0.1:3306/spring_day02
name=root
password=123456
initialSize=5
maxActive=10
maxWait=3000
配置事务管理器
在 config 包下创建 TransactionConfig,并在 SpringConfiguration 类中引入
/**
* 和事务相关的配置类
*/
public class TransactionConfig {
/**
* 用于创建事务管理器对象
* @param dataSource
* @return
*/
@Bean(name="transactionManager")
public PlatformTransactionManager createTransactionManager(DataSource dataSource){
return new DataSourceTransactionManager(dataSource);
}
}
开启 spring 对注解事务的支持
在 SpringConfiguration 类上添加注解 @EnableTransactionManagement
/**
* spring 的配置类,相当于 bean.xml
*/
@Configuration
@ComponentScan("com.zt")
@Import({JdbcConfig.class,TransactionConfig.class})
@PropertySource("druid.properties")
@EnableTransactionManagement
public class SpringConfiguration {
}
在需要事务支持的地方使用 @Transactional 注解
/**
* 账户业务层实现类
*/
@Service("accountService")
@Transactional(propagation = Propagation.REQUIRED, readOnly = false)
public class AccountServiceImpl_OLD implements AccountService {
@Autowired
private AccountDao accountDao;
@Transactional(propagation = Propagation.SUPPORTS, readOnly = true)
public List<Account> findAllAccount() {
return accountDao.findAllAccount();
}
@Transactional(propagation = Propagation.SUPPORTS, readOnly = true)
public Account findAccountById(Integer id) {
return accountDao.findAccountById(id);
}
public void saveAccount(Account account) {
accountDao.saveAccount(account);
}
public void updateAccount(Account account) {
accountDao.updateAccount(account);
}
public void deleteAccount(Integer id) {
accountDao.deleteAccount(id);
}
public void transfer(String sourceName, String targetName, double money) {
// 2.1 查询两个账户信息
Account source = accountDao.findAccountByName(sourceName);
Account target = accountDao.findAccountByName(targetName);
// 2.2 转出账户减钱,转入帐户加钱
source.setMoney(source.getMoney() - money);
target.setMoney(target.getMoney() + money);
// 2.3 更新操作
accountDao.updateAccount(source);
// 2.4 模拟转账异常
// int i = 3 / 0;
accountDao.updateAccount(target);
}
}
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = SpringConfiguration.class)
public class AccountService_OLDTest {
@Autowired
private AccountService accountService;
@Test
public void testTransfer(){
accountService.transfer("aaa","bbb",500);
}
}