版权声明:本文为博主原创文章,未经博主允许不得转载。如需要授权请联系[email protected] https://blog.csdn.net/leeue/article/details/81701580
Spring事务与事务传播行为
一、事务介绍
面试问:
什么是事务?
答:事务就是保证数据的一致性。
Spring事务
Spring事务传播行为
事务的隔离级别有也就是事务的特性?
1、原子:要么全部成功,要么全部失败。不可再分
2、一致性:转账案例就是保证数据的一致性。
3、隔离性:多个事务之间互不影响。
4、持久性: 就是数据提交了就保存在数据库里了。
Spring事务分类:
1、手动事务:自己手动去begin、commit
2、声明式事务:在xml里面配置事务
3、注解方式的事务:加上@transaction。
面试:spring事务分类?两类。
编程事务(手动事务)
声明事务(xml和注解方式)
二、Spring环境配置
注意。注解@Autowired和set注入这种方式不能连用,否则会报错。
set方式:
<bean id="userService" class="com.leeue.service.UserService">
<property name="userDao" ref="userDao"></property>
</bean>
在userService 生成一个set方法
@Autowired方式是直接注入的方式,不需要在配置文件里配置这些bean
三、手动事务(编程事务)
编程事务(手动事务):
原理:获取到依赖数据源的api,在数据源的api中会自动封装手动begin
commit、rollback搭建环境。
编程事务:主要就是先要获取到一个事务管理器。
编程事务代码实现
事务代码:TransactionUtils.java
package com.leeue;
/**
* @classDesc: 功能描述:(手动事务)
* @author:<a href="[email protected]">李月</a>
* @Version:v1.0
* @createTime:2018年8月20日 上午9:59:49
*/
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.stereotype.Component;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.support.DefaultTransactionDefinition;
@Component //只有把这个注入到spring容器中才能使用
public class TransactionUtils {
//1、拿到事务管理器
@Autowired
private DataSourceTransactionManager transactionManager;
//开启事务
public TransactionStatus begin() {
//这里是默认事务
TransactionStatus transaction = transactionManager.getTransaction(new DefaultTransactionDefinition());
//将拿到的事务返回进去,才能提交。
return transaction;
}
//提交事务
public void commit(TransactionStatus transaction) {
//提交事务
transactionManager.commit(transaction);
}
//回滚事务
public void rollback(TransactionStatus transaction) {
transactionManager.rollback(transaction);
}
}
UserService.java
package com.leeue.service;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.TransactionStatus;
import com.leeue.TransactionUtils;
import com.leeue.dao.UserDao;
@Service
public class UserService {
@Autowired
private UserDao userDao;
@Autowired
private TransactionUtils transactionUtils;
public void add() {
TransactionStatus begin = transactionUtils.begin();
userDao.add("HAHA", 20);
int i = 1/0;
transactionUtils.commit(begin);
//只有事务成功提交,才会插入到数据库中去。
}
}
使用try-catch语句能插入到数据库里面去。
使用回滚就不会执行commit了
第四节、事务底层原理分析 声明式事务
AOP管理事务----声明事务和原理
声明事务原理分析:
AOP编程-->环绕通知-->方法之前或方法之后进行执行。
没有异常时执行顺序
环绕通知......前
前置通知......
开启事务
数据库添加数据成功....1
提交事务
环绕通知......后
后置通知.....
运行通知.....
有异常时执行顺序
环绕通知......前
前置通知......
开启事务
数据库添加数据成功....1
回滚事务
后置通知.....
异常通知.....
事务原理:aop编程+环绕通知(开启事务、提交事务)+异常通知(回滚)
有异常时顺序:
开启事务
我是环绕通知......前
前置通知......
数据库添加数据成功....1
后置通知.....
异常通知.....
回滚事务
没有异常时顺序:
开启事务
我是环绕通知......前
前置通知......
数据库添加数据成功....1
我是环绕通知......后
提交事务
后置通知.....
运行通知.....
注意:使用声明式事务方法一定不要加try-catch,要将异常抛出去。
在开发项目时:业务逻辑层(service)不要使用try-catch,要将异常抛出给
上一层。在控制层进行异常捕获。
第五节、事务传播行为
什么是事务传播行为?
答:就是事务的传递。
事务的传播行为分为7种:
PROPAGATION_REQUIRED:
PROPAGATION_SUPPORTS:
PROPAGATION_MANDATORY:
PROPAGATION_REQUIRES_NEW:
PROPAGATION_NOT_SUPPORTED:
PROPAGATION_NEVER:
1、required:支持当前事务,如果当前没有事务就新建一个事务。
这是最常见的选择。
事务传播行为总结:
required:指定当前的方法必须在事务的环境下执行。
如果当前运行的方法已经存在事务,就会加入当前的事务。
required_new:如果当前运行的方法已经存在事务,事务就会挂起,会开启
一个新的事务,执行完后,刚才挂起的事务继续运行。