IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> Java知识库 -> Spring中的事务管理 -> 正文阅读

[Java知识库]Spring中的事务管理

事务的概念

事务:是数据库操作最基本单位,逻辑上的一组操作,要么都成功,如果有一个失败所有操作都失败。

事务的四大特性:

  1. 原子性
  2. 一致性
  3. 隔离性
  4. 持久性

使用代码开启事务的过程(一共分为4步):

public void accountMoney(){
        try {
            //1.手动开启事务
            //2.编写业务逻辑
//            userDao.addMoney();
//            userDao.reduceMoney();
            //3.没有发生异常,提交事务
        } catch (Exception e) {
            //4.发生异常,事务回滚
            e.printStackTrace();
        }
}

????????在JavaEE的开发中主要包含三层结构:controller层(web层)、service层(业务层)、dao层,一般事务添加到业务层(service层)上

????????在spring进行事务的管理主要分为两种方式:编程式事务管理和声明式事务管理,一般常用的是声明式事务管理,下面将介绍声明式事务管理。

声明式事务管理有两种实现方式:

  1. 基于注解的方式
  2. 基于xml配置文件方式

????????这篇博客主要讲解三大部分:①基于xml配置文件和注解的混合方式,②基于完全xml配置文件的方式,③基于完全注解的方式

????????在Spring进行事务声明式事务管理,底层使用的AOP。

目录

1、基于xml配置文件和注解的混合方式

1.1、Spring事务管理API

1.2、在pom文件中引入相关依赖

1.3、在xml文件中完成一系列的配置

1.4、在service类上面添加事务注解

1.5、编写测试类进行测试

1.6、得到运行结果

2、基于完全xml配置文件的方式

2.1、引入相关的依赖

2.2、在xml文件中进行配置

2.3、编写业务逻辑代码

2.4、测试代码的编写

2.5、得到运行结果

3、基于完全注解的方式

3.1、在pom文件中添加相关依赖

3.2、编写配置类TestConfig

3.3、编写业务逻辑代码

3.4、编写测试类

3.5、得到测试运行结果

4、总结


1、基于xml配置文件和注解的混合方式

1.1、Spring事务管理API

????????提供接口PlatformTransactionManager ,接口 PlatformTransactionManage 代表事务管理器,这个接口针对不同的框架提供不同的实现类 (接口 PlatformTransactionManager),其中在spring中以及Mybatis中使用的都是 实现类DataSourceTransactionManager,而Hibernate中使用的是实现类HibernateTransactionManager

1.2、在pom文件中引入相关依赖

? ? ? ? 在依赖引入的时候,要注意每个以来版本之间是否会有冲突,即有没有兼容的问题,不兼容的话,会爆上一篇博客的错误。地址:Error creating bean with name ‘userService‘ defined in file [D:\ajavaproject\coding\atguiguLearnSpri_网恋褙骗八万的博客-CSDN博客

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <packaging>war</packaging>

    <parent>
        <artifactId>atguiguLearnSpring5</artifactId>
        <groupId>org.example</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>Spring5_demo6</artifactId>

    <dependencies>
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid</artifactId>
            <version>1.1.10</version>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.6</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-aop</artifactId>
            <version>5.0.2.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>5.0.2.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-tx</artifactId>
            <version>5.0.2.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-core</artifactId>
            <version>5.0.2.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-jdbc</artifactId>
            <version>5.0.2.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-orm</artifactId>
            <version>5.0.2.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-aspects</artifactId>
            <version>5.0.2.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
            <scope>compile</scope>
        </dependency>
    </dependencies>

    <!--添加这个以后就是用jdk1.8编译,以致于不会出现@Override报错的情况-->
    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.1</version>
                <configuration>
                    <source>1.8</source>
                    <target>1.8</target>
                </configuration>
            </plugin>
        </plugins>
    </build>


</project>

1.3、在xml文件中完成一系列的配置

  1. 开启组件扫描
  2. 连接数据库连接池
  3. 声明JdbcTemplate对象
  4. 创建事务管理器,并注入数据源
  5. 开启事务的注解
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:tx="http://www.springframework.org/schema/tx"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
        http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd">

    <!--  开启组件扫描  -->
    <context:component-scan base-package="com.atguigu.spring5"></context:component-scan>

    <!--连接数据库连接池-->
    <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource"
          destroy-method="close">
        <property name="url" value="jdbc:mysql:///user_db?useUnicode=true&amp;characterEncoding=utf8"/>
        <property name="username" value="root"/>
        <property name="password" value="123456"/>
        <property name="driverClassName" value="com.mysql.jdbc.Driver"/>
    </bean>

    <!--  JdbcTemplate对象  -->
    <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
        <!--   注入dataSource     -->
        <property name="dataSource" ref="dataSource"/>
    </bean>

    <!--  创建事务管理器  -->
    <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <!--   注入数据源     -->
        <property name="dataSource" ref="dataSource"/>
    </bean>

    <!--  开启事务注解  -->
    <tx:annotation-driven transaction-manager="transactionManager"></tx:annotation-driven>


</beans>

1.4、在service类上面添加事务注解

????????@Transactional注解可以加到类上面,也可以把注解添加都方法上面。

? ? ? ? 加到类上面说明这个类的所有方法都添加事务,加到方法上面说明为当前的方法添加事务。

????????service类代码(为了验证事务注解有用性,在执行过程中放置一个除数为0的操作,会抛出异常)

package com.atguigu.spring5.service;

import com.atguigu.spring5.dao.UserDao;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;


/**
 * @Author 不要有情绪的  ljy
 * @Date 2022/9/22 13:51
 * @Description:
 */
@Service
@Transactional
public class UserService {


    @Autowired
    private UserDao userDao;

    public void accountMoney() {

//        try {
//            //1.开启事务
//            //2.编写业务逻辑
        userDao.addMoney();
        int i = 10 / 0;
        userDao.reduceMoney();
//            //3.没有发生异常,提交事务
//        } catch (Exception e) {
//            //4.发生异常,事务回滚
//            e.printStackTrace();
//        }
    }
}

????????dao层代码

package com.atguigu.spring5.dao;

/**
 * @Author 不要有情绪的  ljy
 * @Date 2022/9/22 13:50
 * @Description:
 */
public interface UserDao {

    //增加钱的功能
    public void addMoney();

    //减少钱的功能
    public void reduceMoney();

}

????????dao的实现类daoImpl代码

package com.atguigu.spring5.dao;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Repository;

/**
 * @Author 不要有情绪的  ljy
 * @Date 2022/9/22 13:50
 * @Description:
 */

@Repository
public class UserDaoImpl implements UserDao {
    @Autowired
    private JdbcTemplate jdbcTemplate;

    @Override
    public void addMoney() {
        String sql = "update t_account set money = money + ? where id = ?";
        Object[] args = new Object[]{100,1};
        int update = jdbcTemplate.update(sql, args);
        System.out.println("钱增加成功!" + update);
    }

    @Override
    public void reduceMoney() {
        String sql = "update t_account set money = money - ? where id = ?";
        Object[] args = new Object[]{100, 2};
        int update = jdbcTemplate.update(sql, args);
        System.out.println("钱减少成功!" + update);
    }
}

1.5、编写测试类进行测试

package com.atguigu.spring5.test;

import com.atguigu.spring5.service.UserService;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

/**
 * @Author 不要有情绪的  ljy
 * @Date 2022/9/23 9:29
 * @Description:
 */
public class TestAccount {

    @Test
    public void test(){
        ApplicationContext context = new ClassPathXmlApplicationContext("bean1.xml");
        UserService userService = context.getBean("userService", UserService.class);
        userService.accountMoney();
    }

}

1.6、得到运行结果

????????由于触发了异常导致,整个过程没有全部执行完,因此事务发生了回滚,数据库中的数据没有发生改变。

2、基于完全xml配置文件的方式

2.1、引入相关的依赖

? ? ? ? 依赖和1.2中的依赖一致,不再写出

2.2、在xml文件中进行配置

? ? ? ? 配置文件相较于1.3有点不同,其主要分为以下部分:

  1. 开启组件扫描
  2. 连接数据库连接池
  3. 注册JdbcTemplate对象
  4. 创建事务管理器并注入数据源
  5. 配置通知并配置事务参数(即为哪个方法添加事务)
  6. 配置切入点和切面(即把当前的事务通知添加到切点上)
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:tx="http://www.springframework.org/schema/tx"
       xmlns:aop="http://www.springframework.org/schema/aop"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
        http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd
        http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd">

    <!--  开启组件扫描  -->
    <context:component-scan base-package="com.atguigu.spring5"></context:component-scan>

    <!--连接数据库连接池-->
    <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource"
          destroy-method="close">
        <property name="url" value="jdbc:mysql:///user_db?useUnicode=true&amp;characterEncoding=utf8"/>
        <property name="username" value="root"/>
        <property name="password" value="123456"/>
        <property name="driverClassName" value="com.mysql.jdbc.Driver"/>
    </bean>

    <!--  JdbcTemplate对象  -->
    <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
        <!--   注入dataSource     -->
        <property name="dataSource" ref="dataSource"/>
    </bean>

    <!--  创建事务管理器  -->
    <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <!--   注入数据源     -->
        <property name="dataSource" ref="dataSource"/>
    </bean>

    <!-- 配置通知   -->
    <tx:advice id="txadvice">
        <!--   配置事务参数     -->
        <tx:attributes>
            <!--指明是哪个函数添加事务-->
            <tx:method name="accountMoney" propagation="REQUIRED"/>
            <!--指明为accoun开头的函数添加事务-->
            <!--<tx:method name="account*"/>-->
        </tx:attributes>
    </tx:advice>

    <!-- 配置切入点 和 切面  -->
    <aop:config>
        <!--  配置切入点  -->
        <aop:pointcut id="pt" expression="execution(* com.atguigu.spring5.service.UserService.*(..))"/>
        <!--  配置切面      -->
        <aop:advisor advice-ref="txadvice" pointcut-ref="pt"/>
    </aop:config>


</beans>

2.3、编写业务逻辑代码

? ? ? ? 逻辑代码和1.4章节差不多,只是要删除@Transactional注解

package com.atguigu.spring5.service;

import com.atguigu.spring5.dao.UserDao;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;


/**
 * @Author 不要有情绪的  ljy
 * @Date 2022/9/22 13:51
 * @Description:
 */
@Service
//@Transactional
public class UserService {
    @Autowired
    private UserDao userDao;

    public void accountMoney() {

//        try {
//            //1.开启事务
//            //2.编写业务逻辑
        userDao.addMoney();
        int i = 10 / 0;
        userDao.reduceMoney();
//            //3.没有发生异常,提交事务
//        } catch (Exception e) {
//            //4.发生异常,事务回滚
//            e.printStackTrace();
//        }
    }
}

2.4、测试代码的编写

 @Test
    public void test2(){
        ApplicationContext context = new ClassPathXmlApplicationContext("bean2.xml");
        UserService userService = context.getBean("userService", UserService.class);
        userService.accountMoney();
    }

2.5、得到运行结果

????????与1.6章节一致

3、基于完全注解的方式

3.1、在pom文件中添加相关依赖

? ? ? ? 这儿不再叙说,与前面的章节一致

3.2、编写配置类TestConfig

? ? ? ? 此类的编写是为了代替xml配置文件,并且在该类上添加@Configuration注解,即告诉Spring容器该类是配置类。

package com.atguigu.spring5.config;

import com.alibaba.druid.pool.DruidDataSource;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.EnableTransactionManagement;

/**
 * @Author 不要有情绪的  ljy
 * @Date 2022/9/29 21:53
 * @Description:
 */
@Configuration   //配置类
@ComponentScan(basePackages = {"com.atguigu.spring5"})   //开启注解包扫描
@EnableTransactionManagement   //开启事务
public class TestConfig {
    //创建数据库连接池
    @Bean
    public DruidDataSource getDruidDataSource() {
        DruidDataSource druidDataSource = new DruidDataSource();
        druidDataSource.setDriverClassName("com.mysql.jdbc.Driver");
        druidDataSource.setUrl("jdbc:mysql:///user_db?useUnicode=true&characterEncoding=utf8");
        druidDataSource.setUsername("root");
        druidDataSource.setPassword("123456");
        return druidDataSource;
    }

    //创建JdbcTemplate对象
    @Bean
    public JdbcTemplate getJdbcTemplate(DruidDataSource dataSource) {
        JdbcTemplate jdbcTemplate = new JdbcTemplate();
        jdbcTemplate.setDataSource(dataSource);
        return jdbcTemplate;
    }

    //创建事务管理器
    @Bean
    public DataSourceTransactionManager getDataSourceTransactionManager(DruidDataSource dataSource) {
        DataSourceTransactionManager dataSourceTransactionManager = new DataSourceTransactionManager();
        dataSourceTransactionManager.setDataSource(dataSource);
        return dataSourceTransactionManager;
    }
}

3.3、编写业务逻辑代码

? ? ? ? 与前面的一致,不再描述,但是记得添加上@Transactional注解

3.4、编写测试类

????????由于当前的配置类代替了xml配置为文件,因此测试方法在加载时候有一些变化,此时加载的应该为配置类。

@Test
    public void test3(){
        ApplicationContext context = new AnnotationConfigApplicationContext(TestConfig.class);
        UserService userService = context.getBean("userService", UserService.class);
        userService.accountMoney();
    }

3.5、得到测试运行结果

? ? ? ? 测试得到的结果与前面一致。

4、总结

????????本博客主要讲解了三种spring管理事务的方式,每种方式原理都是一样的,要么使用注解的方式,要么配置文件的方式。整体而言使用注解方式较简单,建议在实际的开发过程中使用注解的方式,简便快速。

学习之所以会想睡觉,是因为那是梦开始的地方。
?(?ˊ?ˋ)??(开心) ?(?ˊ?ˋ)??(开心)?(?ˊ?ˋ)??(开心)?(?ˊ?ˋ)??(开心)?(?ˊ?ˋ)??(开心)
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ------不写代码不会凸的小刘

  Java知识库 最新文章
计算距离春节还有多长时间
系统开发系列 之WebService(spring框架+ma
springBoot+Cache(自定义有效时间配置)
SpringBoot整合mybatis实现增删改查、分页查
spring教程
SpringBoot+Vue实现美食交流网站的设计与实
虚拟机内存结构以及虚拟机中销毁和新建对象
SpringMVC---原理
小李同学: Java如何按多个字段分组
打印票据--java
上一篇文章      下一篇文章      查看所有文章
加:2022-09-30 00:38:26  更:2022-09-30 00:41:22 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2025年3日历 -2025/3/10 15:52:51-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码