首页 > 其他分享 >spring 事务

spring 事务

时间:2023-11-05 12:11:06浏览次数:29  
标签:事务 money spring springframework import org com public

一、事务简介

  1、事务作用:在数据层保障一系列的数据库操作同步成功同步失败

  2、Spring事务作用:在数据层或业务层保障一系列的数据库操作同成功同失败,其是使用JDBC的事务管理器 实现的,如果数据层使用的是JDBC,则可以使用Spring事务

   其是通过内部接口和实现类实现的

// 接口
public interface PlatformTransactionManager {
    void begin();
    void commit(TransactionStatus status) throws TransactionException;
    void rollback(TransactionStatus status) throws TransactionException;
}
// 实现类
public class DataSourceTransactionManager {
    public void begin() {
        System.out.println("开始事务");
    }
    public void commit() {
        System.out.println("提交事务");
    }
    public void rollback() {
        System.out.println("回滚事务");
    }
}

   3、注意事项:

    *  Spring注解式事务通常添加在业务层接口中而不会添加到业务层实现类中,降低耦合

    *  注解式事务可以添加到业务方法上表示当前方法开启事务,也可以添加到接口上表示当前接口所有方法开启事务 

二、快速开始Spring事务

  1、注入相关依赖

  <dependencies>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>5.3.29</version>
        </dependency>

   <dependency>
            <groupId>org.aspectj</groupId>
            <artifactId>aspectjweaver</artifactId>
            <version>1.9.19</version>
        </dependency>

        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid</artifactId>
            <version>1.2.16</version>
        </dependency>

        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis</artifactId>
            <version>3.5.13</version>
        </dependency>

        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>8.0.25</version>
        </dependency>

        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-jdbc</artifactId>
            <version>5.3.12</version>
        </dependency>

        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis-spring</artifactId>
            <version>2.1.1</version>
        </dependency>

        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
            <scope>test</scope>
        </dependency>

        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-test</artifactId>
            <version>5.3.29</version>
        </dependency>
    </dependencies>

  2、设置相关配置

    创建config包,用于存储配置相关文件。

    1) 配置Spring,创建SpringConfig类文件

package com.itheima.config;

import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.context.annotation.PropertySource;
import org.springframework.transaction.annotation.EnableTransactionManagement;

// 告知这是个配置类
@Configuration
// 告知扫描哪些包
@ComponentScan("com.itheima")
// 告知加载哪个配置文件
@PropertySource("classpath:jdbc.properties")
// 告知加载哪些配置文件
@Import({JdbcConfig.class,MybatisConfig.class})
//开启注解式事务驱动
@EnableTransactionManagement
public class SpringConfig {
}

    2)配置JDBC,创建JdbcConfig文件

package com.itheima.config;

import com.alibaba.druid.pool.DruidDataSource;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.transaction.PlatformTransactionManager;

import javax.sql.DataSource;

@Configuration
public class JdbcConfig {
    @Value("${jdbc.driver}")
    private String driver;
    @Value("${jdbc.url}")
    private String url;
    @Value("${jdbc.username}")
    private String userName;
    @Value("${jdbc.password}")
    private String password;

    @Bean
    public DataSource dataSource(){
        DruidDataSource ds = new DruidDataSource();
        ds.setDriverClassName(driver);
        ds.setUrl(url);
        ds.setUsername(userName);
        ds.setPassword(password);
        return ds;
    }

    //配置事务管理器,mybatis使用的是jdbc事务
    @Bean
    public PlatformTransactionManager transactionManager(DataSource dataSource){
        DataSourceTransactionManager transactionManager = new DataSourceTransactionManager();
        transactionManager.setDataSource(dataSource);
        return transactionManager;
    }
}

    3)配置jdbc数据源,在resources下面创建jdbc.properties文件

jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://127.0.0.1:3306/test?useSSL=false
jdbc.username=root
jdbc.password=123456

    4)配置Mybatis,在config文件夹下创建MybatisConfig

package com.itheima.config;

import org.mybatis.spring.SqlSessionFactoryBean;
import org.mybatis.spring.mapper.MapperScannerConfigurer;
import org.springframework.context.annotation.Bean;

import javax.sql.DataSource;

public class MybatisConfig {

    @Bean
    public SqlSessionFactoryBean sqlSessionFactory(DataSource dataSource){
        // 获取SqlSessionFactoryBean对象
        SqlSessionFactoryBean ssfb = new SqlSessionFactoryBean();
        // 别名包
        ssfb.setTypeAliasesPackage("com.itheima.domain");
        // 数据源
        ssfb.setDataSource(dataSource);
        return ssfb;
    }

    @Bean
    public MapperScannerConfigurer mapperScannerConfigurer(){
        MapperScannerConfigurer msc = new MapperScannerConfigurer();
        msc.setBasePackage("com.itheima.dao");
        return msc;
    }
}

  3、创建实体类

  在domain文件夹下创建Account类文件

package com.itheima.domain;

import java.io.Serializable;

// 创建实体类
public class Account implements Serializable {

    private Integer id;
    private String name;
    private Double money;

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Double getMoney() {
        return money;
    }

    public void setMoney(Double money) {
        this.money = money;
    }

    @Override
    public String toString() {
        return "Account{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", money=" + money +
                '}';
    }
}

  4、创建数据dao层  

   在dao文件夹下创建AccountDao接口文件

package com.itheima.dao;

import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Update;

public interface AccountDao {

    @Update("update tbl_account set money = money + #{money} where name = #{name}")
    void inMoney(@Param("name") String name, @Param("money") Double money);

    @Update("update tbl_account set money = money - #{money} where name = #{name}")
    void outMoney(@Param("name") String name, @Param("money") Double money);
}

  5、创建service

  1)创建service接口文件

  在service文件夹下创建AccountService接口文件

package com.itheima.service;

import org.springframework.transaction.annotation.Transactional;

import java.io.FileNotFoundException;
import java.io.IOException;

public interface AccountService {
    /**
     * 转账操作
     * @param out 传出方
     * @param in 转入方
     * @param money 金额
     */
    //配置当前接口方法具有事务
    @Transactional
    public void transfer(String out,String in ,Double money) ;
}

  2)创建service接口实现类文件

  在service文件夹下创建impl文件夹,并在其下面创建AccountServiceImpl实现类文件

  

package com.itheima.service.impl;

import com.itheima.dao.AccountDao;
import com.itheima.service.AccountService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.io.*;

@Service
public class AccountServiceImpl implements AccountService {

    @Autowired
    private AccountDao accountDao;

    public void transfer(String out,String in ,Double money) {
        accountDao.outMoney(out,money);
//        int i = 1/0;
        accountDao.inMoney(in,money);
    }

}

  6、创建测试文件,进行测试

  在test文件夹下创建测试文件

package com.itheima.service;

import com.itheima.config.SpringConfig;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

import java.io.IOException;

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = SpringConfig.class)
public class AccountServiceTest {

    @Autowired
    private AccountService accountService;

    @Test
    public void testTransfer() throws IOException {
        accountService.transfer("Tom","Jerry",100D);
    }

}

  7、最终文件目录

 三、为什么开启spring事务

  如上图所示,第二版块的示例子中执行了两条sql语句,每条语句都是单独的数据库层面的事务(T1,T2),但是如果是业务层中发生了报错,则不会自动回滚,所以,需要在Spring中建立事务(T)。通过Spring中的事务(T1)进行管理数据库的事务(T1、T2)。

  事务角色:

    *  事务管理员:发起事务方,在Spring中通常指代业务层开启事务的方法,如本文例子中的(事务T)

    * 事务协调员:加入事务方,在Spring中通常指代数据层方法(如:T1、T2),也可以是业务层方法

 四、事务相关配置

   1、事务的传播行为

  为了在一个service方法里存在多个事务管理,而不是,所有的数据库操作都必须是全部成功或全部失败。比如,上面将的存钱例子,不论改变账户金额是否成功都进行日志记录。

  1)添加日志记录的dao文件

package com.itheima.dao;

import org.apache.ibatis.annotations.Insert;

public interface LogDao {
    @Insert("insert into tbl_log (info,createDate) values(#{info},now())")
    void log(String info);
}

  2)添加日志记录的service接口类,并设置事务传播

package com.itheima.service;

import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

public interface LogService {
    //propagation设置事务属性:传播行为设置为当前操作需要新事务
    @Transactional(propagation = Propagation.REQUIRES_NEW)
    void log(String out, String in, Double money);
}

  3)实现日志记录接口的实现类

package com.itheima.service.impl;

import com.itheima.dao.LogDao;
import com.itheima.service.LogService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

@Service
public class LogServiceImpl implements LogService {

    @Autowired
    private LogDao logDao;

    public void log(String out,String in,Double money ) {
        logDao.log("转账操作由"+out+"到"+in+",金额:"+money);
    }
}

  4)修改转账service,修改AccountServiceImpl文件

package com.itheima.service.impl;

import com.itheima.dao.AccountDao;
import com.itheima.service.AccountService;
import com.itheima.service.LogService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.io.*;

@Service
public class AccountServiceImpl implements AccountService {

    @Autowired
    private AccountDao accountDao;

    @Autowired
    private LogService logService;
  // 使用try{}finally{}结构,为了保证日志记录一定会执行
    public void transfer(String out,String in ,Double money) {
        try{
            accountDao.outMoney(out,money);
            int i = 1/0;
            accountDao.inMoney(in,money);
        }finally {
            logService.log(out,in,money);
        }
    }

}

  2、事务传播行为包含:

 

标签:事务,money,spring,springframework,import,org,com,public
From: https://www.cnblogs.com/xshan/p/17810179.html

相关文章

  • spring boot集成elk 7.9.1
    一、组件安装es第一次运行es dockerrun-d\ --nameelasticsearch\ --envES_JAVA_OPTS=-"Xms1024m-Xmx1024m"\ --env"discovery.type=single-node"\ --envTZ=Asia/Shanghai\ -p9200:9200/tcp\ -p9300:9300/tcp\ --restart=always\ ......
  • 基于Spring Boot的图书管理系统
    系统关键词图书管理、图书类别、图书借阅、图书归还、图书丢失、图书续借、借还统计、图书统计技术栈后端技术栈:SpringBoot、Shiro、MySQL、Redis、MyBatis-Plus、WebSocket前端技术栈:LayUI、Thymeleaf、jQuery、FontAwesome、WangEditor、zTree功能模块功能截图登......
  • SpringBoot系列之MyBatis Plus自动填充实现
    系列博客专栏:SpringBoot2.0系列博客专栏开发环境JDK1.8SpringBoot2.2.1Maven3.2+Mysql5.7.36开发工具IntelliJIDEAsmartGit项目场景在项目中经常会遇到需要自动填充数据的情况,比如新增一个DO类,里面可能会有id、create_time、modify_time、create_u......
  • 基于springboot的计算机毕业设计帮写
    主要内容:基于springboot的毕业作品设计、基于VUE的、基于安卓APP、基于微信小程序的、原创、设计、毕设、哪里、找我、添加me企鹅numberisone--zero-three-two-three-seven-one-two-one步骤:1.毕设第一步,首先是选题尽量选择新颖的设计题目;2.确定系统功能,完成开题报告;3.编码实......
  • day128-spring boot依赖管理特性与自动配置特性
    springboot依赖管理特性父项目做依赖管理依赖管理:<parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.3.4.RELEASE</version></parent>   其父项目:<......
  • SpringCloudAlibaba引入Gateway统一网关
    一、概述网关是我们服务的守门神,是所有微服务的统一入口,一切请求都要先到网关,再到微服务,它可以帮助我们统一的进行一种操作,处理一些问题。网关的核心功能特性:1.请求路由、负载均衡一切请求都必须先经过gateway网关,但网关不处理业务,而是根据某种规则把请求转发到某个微服务,这个过程......
  • springboot启动报错[main] o.a.catalina.core.AprLifecycleListener
    详细信息为:---[main]o.a.catalina.core.AprLifecycleListener:Anincompatibleversion[1.2.17]oftheApacheTomcatNativelibraryisinstalled,whileTomcatrequiresversion[1.2.34]解决方法:下载对应版本的native文件,地址为https://archive.apache......
  • 部署SpringBoot的学习笔记
    如何部署微服务到服务器上面?一、后端宝塔下载一键部署Java环境,配置jdk1.8的环境变量分模块部署微服务项目、部署nacos和redislinux部署SpringCloud微服务,宝塔部署_微服务项目可以使用宝塔部署吗-CSDN博客利用宝塔面板部署springboot项目_工地精神的博客-CSDN博客云服务器安......
  • Spring新注解
    Spring新注解Spring5.0之后的注解称为新注解==使用上面的注解还不能全部替代xml配置文件,还需要使用注解替代的配置==注解说明@Configuration表示当前类是一个配置类,用于代替配置文件,相当于applicationContext.xml@Bean作用于方法上,用于将方法的返回值存入sprin......
  • spring boot智慧工厂人员定位系统源码,可寻、可视、可防、可控的一体化管控平台
    随着经济的高速发展,现代制造业规模不断扩大,生产车间面积广阔,生产设备日益繁多,生产工人数量多且分散作业,难以进行有效管理和实施全方位风险管控。现代工厂安全管理极需向智慧工厂转型,通过科技手段提升安全及经济效益,成为企业生存发展的关键。智慧工厂人员定位系统通过在作业现场部署......