ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

11、Spring5-事务操作

2022-06-06 04:02:33  阅读:208  来源: 互联网

标签:11 事务管理 事务 Transactional dataSource 100 public Spring5


1、事务的概念

1、什么是事务

(1)事务是数据库操作最基本单元,逻辑上的一组操作,要么都成功,如果有一个失败,那么所有操作都失败

(2)典型场景:银行转账

    lucy转账 100 给mary,lucy少100,mary多100,若出现异常,lucy不会少,mary不会多

2、事务的特性(ACID):

(1)原子性:过程不可分割

(2)一致性:事务执行之前或执行之后数据库都必须,处于一致性状态,不管是错误还是断电,总量不变

(3)隔离性:多事务操作不会相互影响

(4)持久性:事务提交后就会更改表中的数据

 

2、搭建事务操作的基本环境

 

 

1、创建数据库和表,添加记录

 

2、创建service,搭建 dao 和实现类,完成对象创建和注入关系,配置连接池

(1)service 注入 dao ,在 dao 中注入 jdbcTemplate ,在jdbcTemplate 中注入 DataSource

  service中注入dao对象

@Service
public class UserService {
    //注入dao
    @Autowired
    private UserDao userDao;
}

  dao中注入jdbcTemplate对象

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

}

 

   配置文件中jdbcTemplate注入DataSource

<?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:context="http://www.springframework.org/schema/context"
       xmlns:aop="http://www.springframework.org/schema/aop"
       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">

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

    <!--引入外部属性文件-->
    <context:property-placeholder location="classpath:jdbc.properties"/>
    <!--配置数据库连接池-->
    <!-- DruidDataSource dataSource = new DruidDataSource(); -->
    <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
        <!-- dataSource.setDriverClassName("com.mysql.jdbc.Driver");
            set方法注入
        -->
        <!-- 获取properties文件内容,根据key获取,使用spring表达式获取 -->
        <property name="driverClassName" value="${prop.driverClass}"></property>
        <property name="url" value="${prop.url}"></property>
        <property name="username" value="${prop.userName}"></property>
        <property name="password" value="${prop.password}"></property>
    </bean>

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

</beans>

 

3、在dao创建两个方法,一个是多钱的方法,一个是少钱的方法,在Service中创建转账方法

下面是转账方法的基本实现:

dao中的实现如下:

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

    //lucy转账100给mary
    @Override
    public void addMoney() {
        String sql = "update t_account set money=money-? where username=?";
        jdbcTemplate.update(sql,100,"lucy");
    }

    //mary收款100
    @Override
    public void reduceMoney() {
        String sql = "update t_account set money=money+? where username=?";
        jdbcTemplate.update(sql,100,"mary");
    }
}

 

 service的实现方法如下:

@Service
public class UserService {
    //注入dao
    @Autowired
    private UserDao userDao;

    //转账的方法
    public void accountMoney(){
        //lucy少100
        userDao.reduceMoney();
        //mary多100
        userDao.addMoney();
    }
}

 

4、上面代码实现转账功能,正常执行时是没有问题的,但是如果代码执行过程中出现了异常,会产生一些问题

 

(1)上面的问题如何解决?

  使用事务进行解决:逻辑上一组事务要么都成功,一个失败所有都失败

(2)基本步骤如下:

try{
  //第一步 开启事务操作

  //第二步 进行业务操作(转账)
            
  //第三步 没有异常,提交事务
            
}catch (Exception e){
  //第四步 出现异常,事务回滚
}
上述为编程式事务管理,但是在开发中一般使用声明式事务管理

 

3、Spring事务管理介绍

1、事务一般添加到 JavaEE 三层结构的 Service 层(业务逻辑层)

2、在Spring进行进行事务管理操作,

(1)有两种方式:编程式事务管理和声明式事务管理(一般使用声明式)

3、声明式事务管理

(1)基于注解方式(常用)

(2)基于xml配置文件方式

 

4、在Spring中进行声明式事务管理,底层使用 AOP 原理

 

5、Spring事务管理相关API

(1)提供一个接口,代替事务管理器,针对不同的框架提供了不同的实现类

PlatformTransactionManager  代表事务管理器,Spring 做事务管理都是使用这个接口做到的

DataSourceTransactionManager  针对数据库的事务管理

 

PlatformTransactionManager 是一个顶层接口,在接口中针对不同操作数据库的框架,有不同的实现类。

 

4、实现声明式事务管理(注解的方式)

1、在 spring 配置文件中配置事务管理器

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

 

2、在Spring配置文件中,开启事务的注解

(1)在 Spring 的配置文件中引入名称空间 tx

<?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:context="http://www.springframework.org/schema/context"
       xmlns:aop="http://www.springframework.org/schema/aop"
       xmlns:tx="http://www.springframework.org/schema/tx"
       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">

 

(2)开启事务的注解

    <!--开启事务的注解
            transaction-manager 指定事务管理器    
    -->
    <tx:annotation-driven transaction-manager="transactionManager"></tx:annotation-driven>

 

3、在Service 类上面(或在 Service 类中的方法上面)添加事务的注解 @Transactional

(1)@Transactional  可以添加到类上面,也可以添加到方法上面

(2)如果把这个注解添加到类上面,则表示这个类里面的所有方法都添加上了事务

(3)如果式添加到类的方法上面,则只是为这个方法添加了事务

@Service
@Transactional  //@Transactional可以加到类上,也可以加到方法上面
public class UserService {
    //注入dao
    @Autowired
    private UserDao userDao;

    //转账的方法
    public void accountMoney(){
//      //lucy少100
        userDao.reduceMoney();

//      //模拟异常
        int i=10/0;

//      //mary多100
        userDao.addMoney();
    }
}

 

 

4、声明式事务管理参数配置

1、在 service 类上面添加注解 @Transactional,在这个注解里面可以配置事务相关参数

 

2、propagation : 表示事务的传播行为

(1)多事务方法之间进行调用(有事务方法调无事务方法或有事务方法调有事务方法等情况),这个事务是如何进行管理的。如:

 

 默认时 REQUIRED

@Transactional(propagation = Propagation.REQUIRED)

 

3、isolation : 表示事务的隔离级别

(1)事务中有一个特性称为隔离性,多事务操作之间不会产生影响。不考虑隔离性会产生很多问题
(2)有三个读的问题:脏读、不可重复读、虚读(幻读)

  脏读:多个事务之间,一个未提交的事务读取到了另外一个未提交的数据

  

 

   不可重复读:一个未提交的事务,读取到了另一个提交事务修改的事务

  

 

   幻读:一个未提交的事务,读取到了另外一个提交事务添加的数据

(3)通过设置事务的隔离性,解决读的问题

事务的隔离级别:

 

 隔离级别设置:

@Transactional(propagation = Propagation.REQUIRED,isolation = Isolation.REPEATABLE_READ) 

 

在 mysql 中默认使用的时 REAPEATABLE READ 隔离级别

4、timeout : 超时时间

(1)事务在一定的时间内进行提交,否则进行事务的回滚

(2)在 Spring 中,默认值时-1(不超时),可以对时间进行设置,以秒为单位

@Transactional(timeout = -1,propagation = Propagation.REQUIRED,isolation = Isolation.REPEATABLE_READ)

 

5、readonly : 是否只读

(1)读:查询操作,写:添加修改删除操作

(2)readOnly 的默认值时 false ,表示可以进行增加修改删除操作

(3)可以设置 readOnly 的值为 true ,设置成 true 后,只能查询

@Transactional(readOnly = false,timeout = -1,propagation = Propagation.REQUIRED,isolation = Isolation.REPEATABLE_READ)

 

6、rollbackFor : 回滚

(1)设置事务中出现的哪些异常,进行回滚

7、noRollbackFor : 不回滚

 (2)设置事务出现那些异常不进行回滚

 

 

5、使用xml配置文件的方式进行事务的操作

1、在spring配置文件中进行配置

第一步 配置事务管理器

第二步 配置通知(增强)

第三步 配置切入点和切面

    <!--配置通知-->
    <tx:advice id="txAdvice">
        <!--配置事务的相关参数-->
        <tx:attributes>
            <!--指定哪种规则的方法上面添加事务-->
            <tx:method name="accountMoney" propagation="REQUIRED"/><!--可以在后面添加属性-->
<!--            <tx:method name="account*"/>&lt;!&ndash;表示以account开头的方法都进行事务操作&ndash;&gt;-->
        </tx:attributes>
    </tx:advice>
    
    <!--配置切入点和切面-->
    <aop:config>
        <!--配置切入点-->
        <aop:pointcut id="pt" expression="execution(* com.spring5.service.UserService.*(..))"/>
        <!--配置切面-->
        <aop:advisor advice-ref="txAdvice" pointcut-ref="pt"></aop:advisor>
    </aop:config>

 

 

6、完全注解方式进行声明式事务管理

1、创建配置类,使用配置类替代xml配置文件

@Configuration  //代表它是一个配置类
@ComponentScan(basePackages = "com.spring5")    //组件扫描
@EnableTransactionManagement    //开启事务
public class txConfig {
    //创建数据库连接池
    @Bean
    public DruidDataSource getDruidDataSource(){
        DruidDataSource dataSource = new DruidDataSource();
        dataSource.setDriverClassName("com.mysql.cj.jdbc.Driver");
        dataSource.setUrl("jdbc:mysql://localhost:3306/user_db");
        dataSource.setUsername("root");
        dataSource.setPassword("124869");
        return dataSource;
    }
    
    //创建JdbcTemplate对象
    @Bean
    public JdbcTemplate getJdbcTemplate(DataSource dataSource){
        //到ioc容器中,根据类型找到dataSource完成注入
        JdbcTemplate jdbcTemplate = new JdbcTemplate();
        //注入dataSource
        jdbcTemplate.setDataSource(dataSource);
        return jdbcTemplate;
    }
    
    //创建事务管理器对象
    @Bean
    public DataSourceTransactionManager getDataSourceTransactionManager(DataSource dataSource){
        DataSourceTransactionManager transactionManager = new DataSourceTransactionManager();
        transactionManager.setDataSource(dataSource);
        return transactionManager;
    }
}

 

2、在Service中添加注解@Transactional 

@Service
@Transactional(readOnly = false,timeout = -1,propagation = Propagation.REQUIRED,isolation = Isolation.REPEATABLE_READ)  //@Transactional可以加到类上,也可以加到方法上面
public class UserService {
    //注入dao
    @Autowired
    private UserDao userDao;

    //转账的方法
    public void accountMoney(){

        //lucy少100
        userDao.reduceMoney();

        //模拟异常
        int i=10/0;

        //mary多100
        userDao.addMoney();

    }
}    

 测试代码如下:

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

 

标签:11,事务管理,事务,Transactional,dataSource,100,public,Spring5
来源: https://www.cnblogs.com/zhuowen/p/16343886.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有