1.修改pom.xml,引入mybatis和aop依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>1.3.2</version>
</dependency>
2.使用注解配置事务类
package com.config;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import javax.sql.DataSource;
import org.springframework.aop.aspectj.AspectJExpressionPointcut;
import org.springframework.aop.support.DefaultPointcutAdvisor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.transaction.TransactionDefinition;
import org.springframework.transaction.interceptor.NameMatchTransactionAttributeSource;
import org.springframework.transaction.interceptor.RollbackRuleAttribute;
import org.springframework.transaction.interceptor.RuleBasedTransactionAttribute;
import org.springframework.transaction.interceptor.TransactionInterceptor;
import org.springframework.transaction.interceptor.TransactionAttribute;
@Configuration
public class TransactionConfig {
/**
* 主数据源配置 ds1数据源
*/
@Primary
@Bean(name = "ds1Properties")
@ConfigurationProperties(prefix = "spring.datasource.db1")
public DataSourceProperties ds1DataSourceProperties() {
return new DataSourceProperties();
}
/**
* 主数据源 ds1数据源
*/
@Primary
@Bean(name = "dataSource1")
public DataSource ds1DataSource(@Qualifier("ds1Properties") DataSourceProperties dataSourceProperties) {
return dataSourceProperties.initializeDataSourceBuilder().type(HikariDataSource.class).build();
}
@Primary
@Bean("ds1TransactionManager")
public DataSourceTransactionManager getds1TransactionManager(@Qualifier(value = "dataSource1") DataSource ds) {
return new DataSourceTransactionManager(ds);
}
/*事务拦截器*/
@Bean("txAdvice")
public TransactionInterceptor txAdvice(DataSourceTransactionManager txManager){
NameMatchTransactionAttributeSource source = new NameMatchTransactionAttributeSource();
/*只读事务,不做更新操作*/
RuleBasedTransactionAttribute readOnlyTx = new RuleBasedTransactionAttribute();
readOnlyTx.setReadOnly(true);
readOnlyTx.setPropagationBehavior(TransactionDefinition.PROPAGATION_NOT_SUPPORTED );
/*当前存在事务就使用当前事务,当前不存在事务就创建一个新的事务*/
/*RuleBasedTransactionAttribute requiredTx = new RuleBasedTransactionAttribute();
requiredTx.setRollbackRules(
Collections.singletonList(new RollbackRuleAttribute(Exception.class)));
requiredTx.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED);
*/
RuleBasedTransactionAttribute requiredTx = new RuleBasedTransactionAttribute(TransactionDefinition.PROPAGATION_REQUIRED,
Collections.singletonList(new RollbackRuleAttribute(Exception.class)));
requiredTx.setTimeout(5);
Map<String, TransactionAttribute> txMap = new HashMap<>();
txMap.put("add*", requiredTx);
txMap.put("save*", requiredTx);
txMap.put("insert*", requiredTx);
txMap.put("update*", requiredTx);
txMap.put("delete*", requiredTx);
txMap.put("get*", readOnlyTx);
txMap.put("query*", readOnlyTx);
txMap.put("select*", readOnlyTx);
source.setNameMap( txMap );
return new TransactionInterceptor(txManager ,source) ;
}
/**切面拦截规则 参数会自动从容器中注入*/
@Bean
public DefaultPointcutAdvisor defaultPointcutAdvisor(@Qualifier(value = "txAdvice")TransactionInterceptor txAdvice){
DefaultPointcutAdvisor pointcutAdvisor = new DefaultPointcutAdvisor();
pointcutAdvisor.setAdvice(txAdvice);
AspectJExpressionPointcut pointcut = new AspectJExpressionPointcut();
pointcut.setExpression("execution (* com.service.*.*(..))");
pointcutAdvisor.setPointcut(pointcut);
return pointcutAdvisor;
}
}
第三步:修改service、controller、dao、mapper,增加插入逻辑,并在插入数据后,抛出异常,以作测试
package com.service;
import java.util.HashMap;
import java.util.Map;
import org.mybatis.spring.SqlSessionTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.dao.CommDAO;
@Service
public class UserService {
@Autowired
CommDAO dao;
public void insert() throws Exception {
String mapperStr = "UserMapper.insertUser";
Map<String,Object> inMap = new HashMap<String,Object>();
inMap.put("pid", "10");
inMap.put("content", "测试事务");
dao.insert(mapperStr, inMap);
throw new Exception("测试事务回滚");
}
}
这一步代码省略
测试截图
数据并没有成功插入,说明事务成功回滚,事务配置成功