这篇文章主要介绍“@Transactional注解异常报错怎么解决”,在日常操作中,相信很多人在@Transactional注解异常报错怎么解决问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”@Transactional注解异常报错怎么解决”的疑惑有所帮助!接下来,请跟着小编一起来学习吧!
如果在加上@Transactional注解之后报错,先查看程序是否为多数据源,之前专门有一章讲解springboot的多数据源实现。多数据源的情况下加事物注解,有可能会出现问题,以下是解决方案。
一定到在其中一个配置上加上@Primary注解,其他的不要加。
package com.wys.config;
import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.mybatis.spring.SqlSessionTemplate;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.jdbc.DataSourceBuilder;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.jdbc.datasource.DriverManagerDataSource;
import javax.sql.DataSource;
/**
* @program:
* @description: 数据库配置1
* @author: wys
* @create: 2019-12-03 16:20
**/
@Configuration
@MapperScan(basePackages = "com.wys.mapper.**", sqlSessionFactoryRef = "oneSqlSessionFactory")
public class OneDataSourceConfig {
@Value("${spring.datasource.one.driver-class-name}")
String driverClass;
@Value("${spring.datasource.one.url}")
String url;
@Value("${spring.datasource.one.username}")
String userName;
@Value("${spring.datasource.one.password}")
String passWord;
@Primary
@Bean(name = "oneDataSource")
@ConfigurationProperties("spring.datasource.one")
public DataSource masterDataSource() {
DriverManagerDataSource dataSource = new DriverManagerDataSource();
dataSource.setDriverClassName(driverClass);
dataSource.setUrl(url);
dataSource.setUsername(userName);
dataSource.setPassword(passWord);
return dataSource;
}
@Bean(name = "oneSqlSessionFactory")
public SqlSessionFactory sqlSessionFactory(@Qualifier("oneDataSource") DataSource dataSource) throws Exception {
SqlSessionFactoryBean sessionFactoryBean = new SqlSessionFactoryBean();
sessionFactoryBean.setDataSource(dataSource);
sessionFactoryBean.setMapperLocations(new PathMatchingResourcePatternResolver()
.getResources("classpath:mybatis/mapper-postgre/*.xml"));
return sessionFactoryBean.getObject();
}
@Bean(name = "oneSqlSessionFactory")
public SqlSessionTemplate sqlSessionFactoryTemplate(@Qualifier("oneSqlSessionFactory")SqlSessionFactory sqlSessionFactory ) throws Exception {
return new SqlSessionTemplate(sqlSessionFactory);
}
}
加上创建事务管理器
package com.wys.config;
import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.mybatis.spring.SqlSessionTemplate;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.jdbc.DataSourceBuilder;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.jdbc.datasource.DriverManagerDataSource;
import javax.sql.DataSource;
/**
* @program:
* @description: 数据库配置1
* @author: wys
* @create: 2019-12-03 16:20
**/
@Configuration
@MapperScan(basePackages = "com.wys.mapper.**", sqlSessionFactoryRef = "oneSqlSessionFactory")
public class OneDataSourceConfig {
@Value("${spring.datasource.one.driver-class-name}")
String driverClass;
@Value("${spring.datasource.one.url}")
String url;
@Value("${spring.datasource.one.username}")
String userName;
@Value("${spring.datasource.one.password}")
String passWord;
@Primary
@Bean(name = "oneDataSource")
@ConfigurationProperties("spring.datasource.one")
public DataSource masterDataSource() {
DriverManagerDataSource dataSource = new DriverManagerDataSource();
dataSource.setDriverClassName(driverClass);
dataSource.setUrl(url);
dataSource.setUsername(userName);
dataSource.setPassword(passWord);
return dataSource;
}
@Bean(name = "oneSqlSessionFactory")
public SqlSessionFactory sqlSessionFactory(@Qualifier("oneDataSource") DataSource dataSource) throws Exception {
SqlSessionFactoryBean sessionFactoryBean = new SqlSessionFactoryBean();
sessionFactoryBean.setDataSource(dataSource);
sessionFactoryBean.setMapperLocations(new PathMatchingResourcePatternResolver()
.getResources("classpath:mybatis/mapper-postgre/*.xml"));
return sessionFactoryBean.getObject();
}
/
// 创建事务管理器1
@Bean(name = "oneManager1")
public PlatformTransactionManager txManager(@Qualifier("oneDataSource") DataSource dataSource) {
return new DataSourceTransactionManager(dataSource);
}
/////////////////////////
@Bean(name = "oneSqlSessionFactory")
public SqlSessionTemplate sqlSessionFactoryTemplate(@Qualifier("oneSqlSessionFactory")SqlSessionFactory sqlSessionFactory ) throws Exception {
return new SqlSessionTemplate(sqlSessionFactory);
}
}
在需要加注解的地方加上transactionManager 配置即可。
@Transactional(transactionManager ="oneManager1",rollbackFor=Exception.class)
@RestController
public class AController {
@Autowired
AService aService;
// 回滚
@GetMapping("direct")
public void direct() {
aService.testTransactional();
}
// 不回滚
@GetMapping("indirect")
public void indirect() {
aService.testTransactionalIndirect();
}
// 不回滚
@GetMapping("nonPublic")
public void nonPublic() {
aService.testTransactionalNonPublic();
}
// 不回滚
@GetMapping("catchException")
public void catchException() {
aService.testTransactionalCatchException();
}
// 不回滚
@GetMapping("sqlException")
public void sqlException() throws SQLException {
aService.testTransactionalSQLException();
}
// 回滚
@GetMapping("sqlExceptionWithRollbackfor")
public void sqlExceptionWithRollbackfor() throws SQLException {
aService.testTransactionalSQLExceptionWithRollbackfor();
}
}
@Service
public class AService {
@Autowired
TestTableDAO testTableDAO;
// 回滚
@Transactional
public void testTransactional() {
ATestTable er = new ATestTable();
er.setSummary("test");
testTableDAO.save(er);
throw new RuntimeException("exception");
}
// 不回滚: 类内部方法调用本类内部的其他方法并不会引起事务行为,即使被调用方法使用@Transactional注解进行修饰
public void testTransactionalIndirect() {
testTransactional();
}
// 不回滚: @Transaction注解只对方法名为pubic的才生效
@Transactional
void testTransactionalNonPublic() {
ATestTable er = new ATestTable();
er.setSummary("test");
testTableDAO.save(er);
throw new RuntimeException("exception");
}
// 不回滚
@Transactional
public void testTransactionalCatchException() {
ATestTable er = new ATestTable();
er.setSummary("test");
testTableDAO.save(er);
try {
throw new RuntimeException("exception");
} catch (Exception e) {
System.out.println("catch");
}
}
// 不回滚: @Transactional默认情况下只回滚RuntimeException和Error
@Transactional
public void testTransactionalSQLException() throws SQLException {
ATestTable er = new ATestTable();
er.setSummary("test");
testTableDAO.save(er);
throw new SQLException("exception");
}
// 回滚: 指定在 SQLException 异常发生时回滚
@Transactional(rollbackFor = {
SQLException.class
})
public void testTransactionalSQLExceptionWithRollbackfor() throws SQLException {
ATestTable er = new ATestTable();
er.setSummary("test");
testTableDAO.save(er);
throw new SQLException("exception");
}
}
@Repository
public interface TestTableDAO
extends JpaRepository<ATestTable, Integer>, JpaSpecificationExecutor<ATestTable> {
}
@Entity
@Data
@Table(name = "test")
public class ATestTable {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
int id;
@Column(name = "summary", length = 512)
String summary;
}
到此,关于“@Transactional注解异常报错怎么解决”的学习就结束了,希望能够解决大家的疑惑。理论与实践的搭配能更好的帮助大家学习,快去试试吧!若想继续学习更多相关知识,请继续关注亿速云网站,小编会继续努力为大家带来更多实用的文章!
亿速云「云服务器」,即开即用、新一代英特尔至强铂金CPU、三副本存储NVMe SSD云盘,价格低至29元/月。点击查看>>
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。