本文已参与「新人创作礼」活动,一起开启掘金创作之路。
Spring事务管理
举个例子就是你要向别人转账,从你的银行卡扣100块钱到别人的银行卡,中间出现了异常,导致你的银行卡扣了100块钱,但是别人的银行卡的钱没增加。事务管理可以解决这种情况。
spring事务管理做的就是这么一件事:在数据层或业务层保障一系列的数据库同成功、同失败。
1. 前置工作
环境就用之前整合好的mybatis环境。
step1:mapper接口处理
public interface TblAccountMapper {
// @Select("select * from tbl_account")
List<TblAccount> selectAll();
void inMoney(@Param("name") String name, @Param("money") Double money);
void outMoney(@Param("name") String name, @Param("money") Double money);
}
该mapper对应的xml文件
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
<mapper namespace="com.yldclass.dao.TblAccountMapper">
<select id="selectAll" resultType="com.yldclass.pojo.TblAccount">
select * from tbl_account;
</select>
<update id="inMoney">
update tbl_account set money = money + #{money}
where name = #{name};
</update>
<update id="outMoney">
update tbl_account set money = money - #{money}
where name = #{name};
</update>
</mapper>
step2:写一下service层的接口和实现
public interface AccountService {
/**
* @Description: 转账的接口方法
* @Param: [out, in, money]
* @Param: out转出方
* @Param: in 转入方
* @Param: money转出转入金额
*/
public void transfer(String out,String in,Double money);
}
@Component("AccountTransfer")
public class AccountServiceImpl implements AccountService{
//要做一个自动装配注入进去
@Autowired
private TblAccountMapper accountDao;
@Override
public void transfer(String out, String in, Double money) {
accountDao.outMoney(out,money);
//加入一个异常
int i = 1/0;
accountDao.inMoney(in,money);
}
}
这里对应的实现写了一个异常。并且没有去做事务。
【注】这个类要放到spring容器中。
step3:写一个测试类:主要实现从liming的账户转钱到zhangsan的账户。
public class App {
public static void main(String[] args) {
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(SpringConfig.class);
TblAccountMapper account = (TblAccountMapper) ctx.getBean("tblAccountMapper");
AccountService transfer = (AccountService) ctx.getBean("AccountTransfer");
transfer.transfer("liming","zhangsan",100.0);
List<TblAccount> tblAccounts = account.selectAll();
System.out.println(tblAccounts);
}
}
测试结果如下:
liming转了100,但zhangsan没有收到。
2. 开启事务
step1:在业务层接口上添加spring的事务管理。
@Transactional
public void transfer(String out,String in,Double money);
【注意事项】
- Spring注解式事务通常添加在业务层接口中而不会添加到业务层实现类中,降低耦合
- 注解式事务可以添加到业务方法上表示当前方法开启事务,也可以添加到接口上表示当前接口所有方法开启事务
step2:设置事务管理器
//配置事务管理器,mybatis使用的是jdbc事务
@Bean
public PlatformTransactionManager transactionManager(DataSource dataSource){
DataSourceTransactionManager dtm = new DataSourceTransactionManager();
dtm.setDataSource(dataSource);
return dtm;
}
step3:@EnableTransactionManagement注解开启事务驱动
@EnableTransactionManagement
public class SpringConfig {
}
运行结果:
出现异常,数据不变。