@Transactional注解异常报错之多数据源详解

网友投稿 745 2022-09-01


@Transactional注解异常报错之多数据源详解

目录@Transactional注解报错之多数据源1.在配置数据源的同时2.一定要在需要使用事物注解的数据源配置里@Transactional 错误使用的几种场景

@Transactional注解报错之多数据源

如果在加上@Transactional注解之后报错,先查看程序是否为多数据源,之前专门有一章讲解springboot的多数据源实现。多数据源的情况下加事物注解,有可能会出现问题,以下是解决方案。

1.在配置数据源的同时

一定到在其中一个配置上加上@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.autoconfiguhttp://re.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

* http://@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);

dataSourchttp://e.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);

}

}

2.一定要在需要使用事物注解的数据源配置里

加上创建事务管理器

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)

@Transactional 错误使用的几种场景

@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 ATestTsXStlMCable();

er.setSummary("test");

testTableDAO.save(er);

throw new SQLException("exception");

}

}

@Repository

public interface TestTableDAO

extends JpaRepository, JpaSpecificationExecutor {

}

@Entity

@Data

@Table(name = "test")

public class ATestTable {

@Id

@GeneratedValue(strategy = GenerationType.IDENTITY)

int id;

@Column(name = "summary", length = 512)

String summary;

}


版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:Python 之抽丝剥茧聊动态规划(python怎么读)
下一篇:Python【第六篇】面向对象(待完成)(python面向对象吗)
相关文章

 发表评论

暂时没有评论,来抢沙发吧~