1 Spring 事务编程概述
PlatformTransactionManager +TransactionDefinition = TransactionStatus
2 搭建环境
数据库准备一个账户表tb account;
dao层准备一个AccountMapper,包括incrMoney和decrMoney两个方法;service层准备一个transferMoney方法,分别调用incrMoney和decrMoney方法
在applicationContext文件中进行Bean的管理配置
测试正常转账与异常转账
数据库
CREATE TABLE `tb_accout` (
`id` INT NOT NULL AUTO_INCREMENT PRIMARY KEY COMMENT '主键自增',
`account_name` VARCHAR(32) COMMENT '账户名称',
money INT COMMENT '金额'
);
INSERT INTO tb_accout(account_name,money) VALUE('tom',5000);
INSERT INTO tb_accout(account_name,money) VALUE('lucy',5000);
mapper
/**
* @author : msf
* @date : 2023/1/28
*/
@Mapper
public interface AccountMapper {
void incrMoney(@Param("accountName") String accountName, @Param("money")Integer money);
void decrMoney(@Param("accountName") String accountName, @Param("money")Integer money);
}
Service
public interface AccountService {
void transferMoney(String outAccount, String inAccount, Integer money);
}
@Service("accountService")
public class AccountServiceImpl implements AccountService {
@Autowired
private AccountMapper accountMapper;
@Override
public void transferMoney(String outAccount, String inAccount, Integer money) {
accountMapper.decrMoney(outAccount,money);
accountMapper.incrMoney(inAccount,money);
}
}
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"
xmlns:aop="http://www.springframework.org/schema/aop"
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
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd
">
<!--注解组件扫描:扫描指定的基本包及其子包下的类,识别使用@Component注解-->
<context:component-scan base-package="org.example"/>
<context:property-placeholder location="classpath:jdbc.properties"/>
<!--配置数据源信息-->
<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
<property name="driverClassName" value="${jdbc.driver}"></property>
<property name="url" value="${jdbc.url}"></property>
<property name="username" value="${jdbc.username}"></property>
<property name="password" value="${jdbc.password}"></property>
</bean>
<!-- 配置SqlSessionFactoryBean,作用将SqlSessionFactory存储到spring容器-->
<bean class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource"></property>
</bean>
<!-- MapperScannerConfigurer,作用扫描指定的包,产生Mapper对象存储到Spring容器-->
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="basePackage" value="org.example.mapper"></property>
</bean>
</beans>
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"https://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="org.example.mapper.AccountMapper">
<update id="incrMoney">
update tb_accout set money = money + #{money} where account_name = #{accountName}
</update>
<update id="decrMoney">
update tb_accout set money = money - #{money} where account_name = #{accountName}
</update>
</mapper>
结果
3 基于xml声明式事务控制
在业务层进行事务控制;
<!--配置事务平台管理器-->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"/>
</bean>
<!--配置spring 提供好的advisor-->
<tx:advice id="txAdvice" transaction-manager="transactionManager">
<tx:attributes>
<!--事务属性配置,任意方法都需要默认的事务属性-->
<tx:method name="*"/>
</tx:attributes>
</tx:advice>
<!--事务增强的aop-->
<aop:config>
<aop:pointcut id="txPointcut" expression="execution(* org.example.service..*.*(..))"/>
<!--配置织入 spring提供好的通知-->
<aop:advisor advice-ref="txAdvice" pointcut-ref="txPointcut"/>
</aop:config>
事务的传播行为
4 基于注解声明式事务控制
@Transaction
@EnableTransactionManagement 相当于注解扫描