【Spring】事务
【摘要】 这篇文章主要讲了Spring中事务的控制,开启Spring事务保持事务的原子性,以及事务中的事务管理员,事务协调员,事务的相关属性,其中propagation属性较为重要,通过这篇文章,更加深入了解数据库事务。
这篇文章主要介绍Spring中事务相关知识。
事务四大特性:
原子性:事务是一组不可分割的操作,这些操作要么全部执行,要么全部不执行。
一致性:事务执行前后,总数据不会发生改变。
隔离性:事务之间相互独立,互不干扰。
持久性:事务对数据库的改变是永久的,持久化到硬盘。
spring事务作用:
在数据层或业务层保证对数据的操作符合事务四大特性。
1.准备工作
首先准备好数据库中的Account表、数据层的接口AccountMapper、业务层接口AccountService和实现类AccountServiceImpl。
public interface AccountMapper {
/**
* 模拟转账中的出账操作
* @param username 用户名
* @param money 钱数量
* @return 方法执行是否成功的结果
*/
@Update("UPDATE account SET money = money - #{money} WHERE name = #{username}")
int out(@Param("username") String username, @Param("money") Double money);
/**
* 模拟转账中的入账操作
*/
@Update("UPDATE account SET money = money + #{money} WHERE name = #{username}")
int in(@Param("username") String username, @Param("money") Double money);
}
public interface AccountService {
/**
* 转账业务实现
* @param nameOut
* @param nameIn
* @param money
* @return
*/
@Transactional // 开启spring事务
int transfer(String nameOut,String nameIn,Double money);
}
@Service
public class AccountServiceImpl implements AccountService {
@Autowired
private AccountMapper mapper;
@Override
public int transfer(String nameOut, String nameIn, Double money) {
int i = mapper.out(nameOut, money);
// int k = 1/0; // 模拟异常
int j = mapper.in(nameIn, money);
return 0;
}
}
2.开启spring事务
在业务层接口和SpringConfig配置类开启事务支持。
3.编写JDBC事务管理器bean
@Bean
public PlatformTransactionManager transactionManager(DataSource dataSource){
DataSourceTransactionManager manager = new DataSourceTransactionManager();
manager.setDataSource(dataSource);
return manager;
}
4.测试
先看数据库中account表的原始数据
运行结果:
模拟异常:
运行结果:
事务管理员:事务发起方,在Spring中通常指业务层中开启事务的方法(如图中的transfer()方法)
事务协调员:事务加入方,通常指数据层方法,也可以指业务层方法(如图中的out()方法和in()方法)
rollbackFor | noRollBackFor |
---|---|
为除了运行时异常、error错误之外的异常设置事务回滚,默认遇到运行时异常,error之外的错误是不回滚的 | 为一些本该回滚的事务设置不回滚 |
1.MySQL数据库准备log表和实体类
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Log {
private String log;
}
2.准备LogMapper接口和业务层接口以及实现类
public interface LogMapper {
@Insert("INSERT INTO log(info,createTime) VALUES (#{info},now())")
boolean record(@Param("info") String info);
}
public interface LogService {
boolean record(String nameOunt,String nameIn,Double money);
}
@Service
public class LogServiceImpl implements LogService {
@Autowired
private LogMapper mapper;
@Override
public boolean record(String nameOunt, String nameIn, Double money) {
boolean b = mapper.record("从" + nameOunt + "到" + nameIn + "转账:" + money + "元");
return b;
}
}
3.在转账操作中加入记录日记的操作
@Service
public class AccountServiceImpl implements AccountService {
@Autowired
private AccountMapper mapper;
@Autowired
private LogService logService;
@Override
public int transfer(String nameOut, String nameIn, Double money) throws IOException {
try {
int i = mapper.out(nameOut, money);
int j = mapper.in(nameIn, money);
}
finally {
logService.record(nameOut, nameIn, money); // 记录日志操作
}
return 0;
}
}
4.查看运行结果
@Test
public void testTransferAttr() throws IOException {
service.transfer("tom","carry",100D);
}
5.当异常出现时,设置事务传播行为,并将一定要执行的语句放在finally中
事务传播行为原理图:
这篇文章主要讲了Spring中事务的控制,开启Spring事务保持事务的原子性,以及事务中的事务管理员,事务协调员,事务的相关属性,其中propagation属性较为重要,通过这篇文章,更加深入了解数据库事务。
【版权声明】本文为华为云社区用户原创内容,未经允许不得转载,如需转载请自行联系原作者进行授权。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱:
cloudbbs@huaweicloud.com
- 点赞
- 收藏
- 关注作者
作者其他文章
评论(0)