springboot配置手动提交_springboot手动开启事务

Q3:SpringBoot整合Mybatis中如何实现事务控制?

作为一名资深的CURD程序员,事务控制/事务管理是一项不可避免的工作,也是最常见的一项功能,简单说,事务管理就是在执行业务操作时,由于数据操作在顺序执行的过程中,任何一步操作都有可能发生异常,异常会导致后续操作无法完成,此时由于业务逻辑并未正确的完成,之前成功操作数据的并不可靠,需要在这种情况下进行回退。

1、默认的事务管理配置方式:

在引入相关的依赖之后(比如springboot的web组件依赖、父依赖、mysql驱动依赖以及mybatis依赖等)

org.mybatis.spring.boot

mybatis-spring-boot-starter

1.3.0

需要在设计service层的时候,将方法用@Transational注解进行注释,默认的话在抛出Exception.class异常的时候,就会触发方法中所有数据库操作回滚。

而@Transational注解也拥有许多的参数,比如:rollbackFor:可以指定需要进行回滚的异常,指定Class对象数组,且该Class必须继承自Throwable;

value:用于在多数据源的情况下,进行事务管理器的指定(下面描述下多数据源事务这种情况);

noRollbackFor:有rollbackFor自然有noRollbackFor,顾名思义,用于指定不需要进行回滚的异常;

readOnly:是读写还是只读事务,默认是false,读写;

还有许多,不一一描述了....

实例:@Service

public class TestTransactionalService

@Autowired

private TestMapper testMapper;

@Transactional//当抛出Exception的时候,将进行回滚操作

public int insertTest(TestEntity testEntity) {

testEntity.setName("get out! helloService")

return testMapper.insertOne(testEntity);

}

}

另外,在SpringBoot的启动类中,需要增加@EnableTransactionManagement注解,用于启动事务管理。

实例:@EnableTransactionManagement

@SpringBootApplication

public class Application {

public static void main(String[] args) {

SpringApplication.run(Application.class, args);

}

}

至此,SpringBoot整合Mybatis的单数据源的事务管理便配置完成

2、多数据源的事务配置方式:

第一种方式基本上满足了普通项目的事务管理功能, 但当项目是比较大型的项目的时候(比如电商项目),可能会存在多个数据源,这时候会出现多个事务管理器,也就需要在声明的时候为不同数据源的数据操作指定不同的事务管理器。

1)首先,需要引入数据源依赖

com.alibaba

druid

1.0.19

2)配置properties配置文件(或者yml文件...)#主数据源,多数据源的情况下,需要指定主数据源,在后续的config中进行,此时我们将#base数据源作为主数据源来看待~

spring.datasource.base.jdbc-url=jdbc:mysql://localhost:3306/test1、spring.datasource.base.username=root

spring.datasource.base.password=root

spring.datasource.base.driver-class-name=com.mysql.jdbc.Driver

#从数据源

spring.datasource.second2.jdbc-url=jdbc:mysql://localhost:3306/test2、spring.datasource.second2.username=root

spring.datasource.second2.password=root

spring.datasource.second2.driver-class-name=com.mysql.jdbc.Driver

3)新增配置类,读取配置文件,进行数据源的配置

注意,配置类需要对DataSource、DataSourceTransactionManager、SqlSessionFactory 、SqlSessionTemplate四个数据项进行配置;

其中DataSource类型需要引入javax.sql.DataSource;

配置主数据源:

如上文所说,当系统中有多个数据源时,必须有一个数据源为主数据源,在配置类中我们使用@Primary修饰。

通过@MapperScan注解对指定dao包建立映射,确保在多个数据源下,自动选择合适的数据源,而在service层里不需要做特殊说明,否则需要通过@Transactional的value属性进行指定@Configuration

@MapperScan(basePackages = "com.livinghome.base", sqlSessionTemplateRef = "baseSqlSessionTemplate",sqlSessionFactoryRef = "baseSqlSessionFactory")

public class BaseDataSourceConfig {

/**读取base数据源**/

@Bean(name = "baseDataSource")

@ConfigurationProperties(prefix = "spring.datasource.base")

@Primary

public DataSource setDataSource() {

return DataSourceBuilder.create().build();

}

@Bean(name = "baseTransactionManager")

@Primary

public DataSourceTransactionManager setTransactionManager(@Qualifier("baseDataSource") DataSource dataSource) {

return new DruidDataSource();

}

@Bean(name = "baseSqlSessionFactory")

@Primary

public SqlSessionFactory setSqlSessionFactory(@Qualifier("baseDataSource") DataSource dataSource) throws Exception {

SqlSessionFactoryBean bean = new SqlSessionFactoryBean();

bean.setDataSource(dataSource);

bean.setMapperLocations(new PathMatchingResourcePatternResolver().getResources("classpath:mapper/base/*.xml"));

return bean.getObject();

}

@Bean(name = "baseSqlSessionTemplate")

@Primary

public SqlSessionTemplate setSqlSessionTemplate(@Qualifier("baseSqlSessionFactory") SqlSessionFactory sqlSessionFactory) throws Exception {

return new SqlSessionTemplate(sqlSessionFactory);

}

}

配置从数据源:@Configuration

@MapperScan(basePackages = "com.livinghome.second2", sqlSessionTemplateRef = "zentaoSqlSessionTemplate",sqlSessionFactoryRef = "zentaoSqlSessionFactory")

public class Second2DataSourceConfig {

@Bean(name = "second2DataSource")

@ConfigurationProperties(prefix = "spring.datasource.second2")

public DataSource setDataSource() {

return new DruidDataSource();

}

@Bean(name = "second2TransactionManager")

public DataSourceTransactionManager setTransactionManager(@Qualifier("second2DataSource") DataSource dataSource) {

return new DataSourceTransactionManager(dataSource);

}

@Bean(name = "second2SqlSessionFactory")

public SqlSessionFactory setSqlSessionFactory(@Qualifier("second2DataSource") DataSource dataSource) throws Exception {

SqlSessionFactoryBean bean = new SqlSessionFactoryBean();

bean.setDataSource(dataSource);

bean.setMapperLocations(new PathMatchingResourcePatternResolver().getResources("classpath:mapper/second2/*.xml"));

return bean.getObject();

}

@Bean(name = "second2SqlSessionTemplate")

public SqlSessionTemplate setSqlSessionTemplate(@Qualifier("second2SqlSessionFactory") SqlSessionFactory sqlSessionFactory) throws Exception {

return new SqlSessionTemplate(sqlSessionFactory);

}

}

4)到了这里,我们基本的多数据源事务管理便已经完成了(真的)....

对于service层,不需要进行事务管理器的指定,因为我们上面使用了@MapperScan进行了包指定,当然也可以手动指定,方式便是 @Transactional(transactionManager="baseTransactionManager")

便可手动指定为base数据源。

另外,还有分布式事务管理,也就是在一次操作中,操作了不同的数据源的情况,对于service而言,便是在一次service里调用了两个数据源的方法,这种情况常见于微服务架构中,例如电商系统(第二次使用电商系统举例..)。

从百度上copy了一个简单的下单流程:

在微服务中,2、3、4步骤是涉及了3个系统以及3个数据库的,当某个操作出现问题时,会出现多数据源的事务管理问题,传统的方式是通过将不同数据源的事务都注册到一个全局事务中(可以通过jpa+atomikos来进行),但有大神告诉我这种方式性能差,具体还未有实践,不是很清楚。

我说完了... 因为对微服务架构学习还在进行中,所以对于分布式事务问题我还没有太多的理解和实践,等我回来....

同时,欢迎大神为我指点明路!!——没事待在家里不出门的 居家程序员。(我不想脱发!)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值