1、@Transactional
项目只要整合了JDBC等数据源后,不需要导入额外的包
在接口、接口方法、类以及类方法上添加 @Transactional
即可
- 常用配置
参 数 名 称 | 功 能 描 述 |
---|---|
readOnly | 该属性用于设置当前事务是否为只读事务,设置为true表示只读,false则表示可读写,默认值为false。例如:@Transactional(readOnly=true) |
rollbackFor | 该属性用于设置需要进行回滚的异常类数组,当方法中抛出指定异常数组中的异常时,则进行事务回滚。例如:指定单一异常类:@Transactional(rollbackFor=RuntimeException.class)指定多个异常类:@Transactional(rollbackFor={RuntimeException.class, Exception.class}) |
rollbackForClassName | 该属性用于设置需要进行回滚的异常类名称数组,当方法中抛出指定异常名称数组中的异常时,则进行事务回滚。例如:指定单一异常类名称@Transactional(rollbackForClassName=”RuntimeException”)指定多个异常类名称:@Transactional(rollbackForClassName={“RuntimeException”,”Exception”}) |
noRollbackFor | 该属性用于设置不需要进行回滚的异常类数组,当方法中抛出指定异常数组中的异常时,不进行事务回滚。例如:指定单一异常类:@Transactional(noRollbackFor=RuntimeException.class)指定多个异常类:@Transactional(noRollbackFor={RuntimeException.class, Exception.class}) |
noRollbackForClassName | 该属性用于设置不需要进行回滚的异常类名称数组,当方法中抛出指定异常名称数组中的异常时,不进行事务回滚。例如:指定单一异常类名称:@Transactional(noRollbackForClassName=”RuntimeException”)指定多个异常类名称:@Transactional(noRollbackForClassName={“RuntimeException”,”Exception”}) |
propagation | 该属性用于设置事务的传播行为。例如:@Transactional(propagation=Propagation.NOT_SUPPORTED,readOnly=true) |
isolation | 该属性用于设置底层数据库的事务隔离级别,事务隔离级别用于处理多事务并发的情况,通常使用数据库的默认隔离级别即可,基本不需要进行设置 |
timeout | 该属性用于设置事务的超时秒数,默认值为-1表示永不超时 |
@Service
@Transactional(rollbackFor = {RuntimeException.class,Error.class})
public class UserServiceImpl implements UserService{
@Autowired
UserMapper userMapper;
@Override
//@Transactional(rollbackFor = {RuntimeException.class,Error.class},readOnly = true)
public List<User> queryUserList() {
return userMapper.queryUserList();
}
}
如果需要添加事务的方法或类比较多,要逐个进行添加,比较麻烦
2、AOP
+ xml
1)导入 AOP 依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
2)配置 transaction-management.xml
在 resources 目录下新建 config 目录
config/transaction-management.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:tx="http://www.springframework.org/schema/tx"
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/tx
http://www.springframework.org/schema/tx/spring-tx.xsd
http://www.springframework.org/schema/aop
https://www.springframework.org/schema/aop/spring-aop.xsd">
<!--配置事务通知,即方法的增强-->
<tx:advice id="txAdvice" transaction-manager="transactionManager">
<!--需要配置事务的方法-->
<!--事务的传播特性-->
<tx:attributes>
<tx:method name="get*" propagation="REQUIRED" read-only="true" rollback-for="RuntimeException.class,Error.class"/>
<tx:method name="select*" propagation="REQUIRED" read-only="true" rollback-for="RuntimeException.class,Error.class"/>
<tx:method name="query*" propagation="REQUIRED" read-only="true" rollback-for="RuntimeException.class,Error.class"/>
<tx:method name="load*" propagation="REQUIRED" read-only="true" rollback-for="RuntimeException.class,Error.class"/>
<tx:method name="search*" propagation="REQUIRED" read-only="true" rollback-for="RuntimeException.class,Error.class"/>
<tx:method name="find*" propagation="REQUIRED" read-only="true" rollback-for="RuntimeException.class,Error.class"/>
<tx:method name="*" propagation="REQUIRED" rollback-for="RuntimeException.class,Error.class"/>
</tx:attributes>
</tx:advice>
<!--配置事务切入-->
<aop:config>
<aop:pointcut id="txPointCut" expression="execution(* com.tuwer.service.*Impl.*(..))"/>
<aop:advisor advice-ref="txAdvice" pointcut-ref="txPointCut"/>
</aop:config>
</beans>
3)启用 xml
在入口程序同级目录下,新建 config 目录
// 配置类
@Configuration
// 导入配置文件资源
@ImportResource("classpath:/config/transaction-management.xml")
public class TransactionManagementConfig {
}
业务类中不需要再做事务配置
com.tuwer.service
包下所有以Impl
结尾的类中所有方法都添加了事务
3、AOP
+ @Aspect
类或方法比较多时,推荐使用
1)导入 AOP 依赖
同2
2)自定义切面配置类
@Aspect
表明这是一个切面类
@Aspect
@Configuration
public class TransactionAdviceConfig {
/**
* 切入点
*/
private static final String AOP_POINTCUT_EXPRESSION = "execution(* com.tuwer.service.*Impl.*(..))";
/**
* 注入事务管理器
*/
@Autowired
private TransactionManager transactionManager;
/**
* 定义事务增强
* @return
*/
@Bean
public TransactionInterceptor txAdvice() {
NameMatchTransactionAttributeSource source = new NameMatchTransactionAttributeSource();
// 查询等;只读
DefaultTransactionAttribute txAttr_REQUIRED_READONLY = new DefaultTransactionAttribute();
txAttr_REQUIRED_READONLY.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED);
txAttr_REQUIRED_READONLY.setReadOnly(true);
source.addTransactionalMethod("get*", txAttr_REQUIRED_READONLY);
source.addTransactionalMethod("select*", txAttr_REQUIRED_READONLY);
source.addTransactionalMethod("query*", txAttr_REQUIRED_READONLY);
source.addTransactionalMethod("load*", txAttr_REQUIRED_READONLY);
source.addTransactionalMethod("search*", txAttr_REQUIRED_READONLY);
source.addTransactionalMethod("find*", txAttr_REQUIRED_READONLY);
source.addTransactionalMethod("list*", txAttr_REQUIRED_READONLY);
source.addTransactionalMethod("count*", txAttr_REQUIRED_READONLY);
source.addTransactionalMethod("is*", txAttr_REQUIRED_READONLY);
// 增删改
DefaultTransactionAttribute txAttr_REQUIRED = new DefaultTransactionAttribute();
txAttr_REQUIRED.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED);
source.addTransactionalMethod("*", txAttr_REQUIRED);
return new TransactionInterceptor(transactionManager, source);
}
/**
* 织入事务
* @return
*/
@Bean
public Advisor txAdviceAdvisor() {
// 切入点
AspectJExpressionPointcut pointcut = new AspectJExpressionPointcut();
pointcut.setExpression(AOP_POINTCUT_EXPRESSION);
return new DefaultPointcutAdvisor(pointcut, txAdvice());
}
}