SpringBoot的事务管理以及配置多个数据源

事务的概念

什么是事务:就是指多个sql语句作为单一逻辑单元进行执行的操作,要么全部执行,要么全都不执行

特性:ACID
原子性:多条sql语句,要么全执行,要么全不执行
一致性:事务完成,必须使所有的数据保持一致
隔离性:指当前的事务必须与与其他事务隔离开(不能同时操作一个数据)
持久性:事务执行完毕之后,对数据的影响是永久的

如何实现事务?

	@Override
    @Transactional
    public void testTran(User user){
       usermapper.update(user);
       int a=2/0;
        usermapper.delete(user);
    }

当我们在实现的方法上添加 @Transactional注解时,改方法就已经有了事务的支持。通俗的说,当整个方法运行时,首先运行完毕,期间遇到的所有sql语句先暂放起来,如何这个方法没有报错,那么所有的sql语句一起执行

多数据源的配置

看来网上的教程,很多都一样,但是当自己做起来的时候,问题可多了!中间一直出错,一直在解决错误,总算是成功了!

1.添加maven依赖
		<dependency>
			<groupId>mysql</groupId>
			<artifactId>mysql-connector-java</artifactId>
			<scope>runtime</scope>
		</dependency>

        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.18.8</version>
            <scope>provided</scope>
        </dependency>

        <!--  整合spring-data-jpa-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jpa</artifactId>
        </dependency>
2.新建一个实体
import lombok.Data;
import javax.persistence.*;
import java.io.Serializable;

/**
 * @author Administrator
 */
@Data
//jpa下的注解
@Entity
@Table(name="t_user")
public class User implements Serializable{

    private static final long serialVersionUID = -6503710493488425450L;

    @Id
    @GeneratedValue
    @Column(name = "id")
    private Integer id;
    @Column(name = "loginid")
    private String loginid;
    @Column(name = "pwd")
    private String pwd;
    @Column(name = "roleid")
    private Integer roleid;
    @Column(name = "username")
    private String username;
    @Column(name = "deleteflag")
    private Byte deleteflag;
    @Column(name = "classid")
    private Integer classid;
    @Column(name = "openid")
    private String openid;
    @Column(name = "enablesign")
    private Byte enablesign;
    @Column(name = "type")
    private Byte type;
    @Column(name = "belongs")
    private Byte belongs;
    @Column(name = "blemac")
    private String blemac;
    @Column(name = "region")
    private Byte region;
    @Column(name = "begintime")
    private String begintime;

    @Transient
    private Integer stepnums;

    public User(String loginid, String pwd, String username) {
        this.loginid = loginid;
        this.pwd = pwd;
        this.username = username;
    }
}
3.配置多数据源
spring:
    datasource:
          master:
                jdbc-url: jdbc:mysql://localhost:3306/springboot?serverTimezone=Asia/Shanghai
                username: root
                password: zhou
                driver-class-name: com.mysql.jdbc.Driver
          slave:
                jdbc-url: jdbc:mysql://localhost:3306/zgq?serverTimezone=Asia/Shanghai
                username: root
                password: zhou
                driver-class-name: com.mysql.jdbc.Driver

注意: 这里需要用jdbc-url,否则会报错:

jdbcUrl is required with driverClassName.
4.配置主数据源配置文件
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.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.jdbc.DataSourceBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;

import javax.sql.DataSource;


/**
 * 主数据库连接
 */
//表示这个类为一个配置类
@Configuration
// 配置mybatis的接口类放的地方
@MapperScan(basePackages = "com.example.echart.mapper.master", sqlSessionTemplateRef = "masterSqlSessionTemplate")
public class MasterDataSourceConfig {

        // 将这个对象放入Spring容器中
        @Bean(name = "masterDataSource")
        // 读取application.properties中的配置参数映射成为一个对象,prefix表示参数的前缀
        @ConfigurationProperties(prefix = "spring.datasource.master")
        // 表示这个数据源是默认数据源
        @Primary
        public DataSource testDataSource() {
        return DataSourceBuilder.create().build();
        }

        /**
         *   @Qualifier表示查找Spring容器中名字为masterDataSource的对象
         * @param dataSource
         * @return
         * @throws Exception
         */
        @Bean(name = "masterSqlSessionFactory")
        @Primary
        public SqlSessionFactory testSqlSessionFactory(@Qualifier("masterDataSource") DataSource dataSource)
        throws Exception {
        SqlSessionFactoryBean bean = new SqlSessionFactoryBean();
        bean.setDataSource(dataSource);
        return bean.getObject();
        }

        @Bean(name = "masterTransactionManager")
        @Primary
        public DataSourceTransactionManager testTransactionManager(@Qualifier("masterDataSource") DataSource dataSource) {
        return new DataSourceTransactionManager(dataSource);
        }

        @Bean(name = "masterSqlSessionTemplate")
        @Primary
        public SqlSessionTemplate testSqlSessionTemplate(
        @Qualifier("masterSqlSessionFactory") SqlSessionFactory sqlSessionFactory) throws Exception {
        return new SqlSessionTemplate(sqlSessionFactory);
        }
        }
5.配置次数据源配置文件
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.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.jdbc.DataSourceBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import javax.sql.DataSource;

/**
 * 从数据库连接
 */
//这里配置mapper所在的包
@Configuration
@MapperScan(basePackages = "com.example.echart.mapper.slave", sqlSessionTemplateRef = "slaveSqlSessionTemplate")
public class SlaveDataSourceConfig {

        // 将这个对象放入Spring容器中
        @Bean(name = "slaveDataSource")
        // 读取application.properties中的配置参数映射成为一个对象,prefix表示参数的前缀
        @ConfigurationProperties(prefix = "spring.datasource.slave")
        public DataSource testDataSource() {
        return DataSourceBuilder.create().build();
        }

    /**
     *   @Qualifier表示查找Spring容器中名字为slaveDataSource的对象
     * @param dataSource
     * @return
     * @throws Exception
     */
        @Bean(name = "slaveSqlSessionFactory")
        public SqlSessionFactory testSqlSessionFactory(@Qualifier("slaveDataSource") DataSource dataSource)
        throws Exception {
        SqlSessionFactoryBean bean = new SqlSessionFactoryBean();
        bean.setDataSource(dataSource);
        return bean.getObject();
        }

        @Bean(name = "slaveTransactionManager")
        public DataSourceTransactionManager testTransactionManager(@Qualifier("slaveDataSource") DataSource dataSource) {
        return new DataSourceTransactionManager(dataSource);
        }

        @Bean(name = "slaveSqlSessionTemplate")
        public SqlSessionTemplate testSqlSessionTemplate(
        @Qualifier("slaveSqlSessionFactory") SqlSessionFactory sqlSessionFactory) throws Exception {
        return new SqlSessionTemplate(sqlSessionFactory);
        }
        }
6.新建控制层,查询多数据库的数据
@Controller
@RequestMapping(value={"/user"})
public class UserController {
@Autowired
    User1Mapper user1Mapper;
    @Autowired
    User2Mapper user2Mapper;

    @RequestMapping(value = "getUser1")
    @ResponseBody
    public Object getUser1(){
        return user1Mapper.getUserById(1);
    }

    @RequestMapping(value = "getUser2")
    @ResponseBody
    public Object getUser2(){
        return user2Mapper.getUserById(1);
    }
 }
7.总是报错的缘由

1.首先这是我的项目目录
在这里插入图片描述
在加入多数据源之前,我就已经整合了很多的技术,比如mapper在加入的时候,默认的扫描路径mapper文件,所以当我在mapper文件下加入文件夹的时候,默认的数据源路径后面增加了master路径,一般来说spring boot默认的扫描路径是启动类当前的包和子包,拿我当前的项目来说,启动类的路径是:com.example.echart,数据接口类是它的子包:com.example.echart.mapper,但是当我们在mapper中加入文件夹的时候,项目是扫描不到的,所以就会出现注入的一个报错

Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}

解决的办法就是在启动类上增加注解,告诉项目默认mapper的接口路径

//指定mapper文件的位置
@MapperScan("com.example.echart.mapper")
7.运行项目,查看运行结构

在这里插入图片描述
在这里插入图片描述
这样就可以看到,我们的两个方法已经从两个数据库中取出了数据

  • 6
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值