基于 XML 事务配置
一、添加 Maven 依赖
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.1.5.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-tx</artifactId>
<version>5.1.5.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aspects</artifactId>
<version>5.1.5.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>5.1.5.RELEASE</version>
</dependency>
二、创建数据库 SQL
CREATE TABLE account (id INT PRIMARY KEY AUTO_INCREMENT, name VARCHAR(20), money FLOAT);
三、创建与数据库表对应的实体类
public class Account implements Serializable {
private Integer id;
private String name;
private Float money;
// 省略 Get、Set 方法
}
四、创建映射类
public class AccountRowMapper implements RowMapper<Account> {
public Account mapRow(ResultSet resultSet, int i) throws SQLException {
Account account = new Account();
account.setId(resultSet.getInt("id"));
account.setName(resultSet.getString("name"));
account.setMoney(resultSet.getFloat("money"));
return account;
}
}
五、Dao 层接口
public interface IAccountDao {
/**
* 根据名称查询账户信息
* @param name
* @return
*/
Account findAccountByName(String name);
/**
* 更新账户信息
* @param account
*/
void updateAccount(Account account);
}
六、Dao 层实现类
public class AccountDaoImpl extends JdbcDaoSupport implements IAccountDao {
public Account findAccountByName(String name) {
List<Account> list = getJdbcTemplate().query("select * from account where name = ? ",new AccountRowMapper(),name);
return list.get(0);
}
public void updateAccount(Account account) {
getJdbcTemplate().update("update account set money = ? where id = ? ",account.getMoney(),account.getId());
}
}
七、业务层接口
public interface IAccountService {
/**
* 转账
* @param sourceName 转出账户名称
* @param targeName 转入账户名称
* @param money 转账金额
*/
void transfer(String sourceName,String targeName,Float money);
}
八、业务层实现类
public class AccountServiceImpl implements IAccountService {
private IAccountDao accountDao;
public void setAccountDao(IAccountDao accountDao) {
this.accountDao = accountDao;
}
/**
* 转账
* @param sourceName 转出账户名称
* @param targeName 转入账户名称
* @param money 转账金额
*/
public void transfer(String sourceName, String targeName, Float money) {
//1.根据名称查询两个账户
Account source = accountDao.findAccountByName(sourceName);
Account target = accountDao.findAccountByName(targeName);
//2.修改两个账户的金额
source.setMoney(source.getMoney()-money);//转出账户减钱
target.setMoney(target.getMoney()+money);//转入账户加钱
//3.更新两个账户
accountDao.updateAccount(source);
int i=1/0;
accountDao.updateAccount(target);
}
}
九、Spring 配置文件
<?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: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">
<!-- 配置 Service -->
<bean id="accountService" class="chu.yi.bo.AccountServiceImpl">
<property name="accountDao" ref="accountDao"/>
</bean>
<!-- 配置 Dao -->
<bean id="accountDao" class="chu.yi.bo.AccountDaoImpl">
<property name="dataSource" ref="dataSource"/>
</bean>
<!-- Spring 内置数据源 -->
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql:///test"/>
<property name="username" value="root"/>
<property name="password" value="123456"/>
</bean>
<!-- 配置事务管理器 -->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<!-- 注入 DataSource -->
<property name="dataSource" ref="dataSource"/>
</bean>
<!-- 事务配置 -->
<tx:advice id="txAdvice" transaction-manager="transactionManager">
<!-- 配置事务属性 -->
<tx:attributes>
<tx:method name="*" read-only="false" propagation="REQUIRED"/>
</tx:attributes>
</tx:advice>
<!-- 配置 AOP -->
<aop:config proxy-target-class="true">
<aop:pointcut id="pt1" expression="execution(* chu.yi.bo.AccountServiceImpl.*(..))"/>
<aop:advisor advice-ref="txAdvice" pointcut-ref="pt1"/>
</aop:config>
</beans>
十、测试
public void testTX() {
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("Application.xml");
IAccountService accountService = (AccountServiceImpl) applicationContext.getBean("accountService");
accountService.transfer("xiaoming","xiaohong", (float) 100);
}