Spring学习总结(5)--- Spring声明式事务

本文详细介绍了Spring中的声明式事务,包括事务的四大特性(ACID)、声明式事务的优势、如何配置Spring事务管理器,以及事务的传播行为。通过一个具体的案例,展示了如何在Spring中设置事务以确保数据库操作的原子性和一致性。事务处理是项目开发中的关键,Spring的声明式事务管理简化了事务管理代码,使得事务管理更加便捷。
摘要由CSDN通过智能技术生成

1. 事务

事务在项目开发过程中非常重要!涉及到数据的完整性和一致性问题,不容马虎!

1.1 什么是事务

事务就是把一系列的动作当成一个独立的工作单元,这些动作要么全部完成,要么全部不起作用。就是把一系列的操作当成原子性去执行。

事务的四大特性:ACID

  • 原子性(automicity):

    事务是原子性操作,由一系列动作组成,事务的原子性确保动作要么全部完成,要么完全不起作用。

  • 一致性(consistency):

    一旦所有事务动作完成,事务就要被提交。数据和资源处于一种满足业务规则的一致性状态中。

  • 隔离性(isolation):

    可能多个事务会同时处理相同的数据,因此每个事务都应该与其他事务隔离开来,防止数据损坏。

  • 持久性(durablity):

    事务一旦完成,无论系统发生什么错误,结果都不会受到影响。通常情况下,事务的结果被写到持久化存储器中。

事务要么都成功!要么都不成功!

2. 声明式事务

Spring支持两种事务处理机制:

  • 编程式事务:

    把所有事务的代码写在业务中;

    必须在每个事务操作业务逻辑中包含额外的事务管理代码。

  • 声明式事务:

    将事务管理代码从业务方法中分离出来,以声明的方式来实现事务管理。

    使用AOP横切进去;一般都会使用声明式事务

    Spring中通过Spring AOP框架支持声明式事务管理。

要开启 Spring 的事务处理功能,在 Spring 的配置文件中创建一个 DataSourceTransactionManager 对象:

<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
  <constructor-arg ref="dataSource" />
</bean>

使用Spring进行事务通知,需要导入约束文件:<tx></tx>

事务的传播行为:

事务方法被另一个事务方法调用时,必须指定事务应该如何传播。例如方法可能继续在现有事务中运行,也可能开启一个新的事务,并在自己的事务运行。spring中的事务传播行为可以由传播属性指定。spring指定了7种类传播行为。

常用默认的传播行为REQUIRED。

PROPAGATION_REQUIRED–支持当前事务,如果当前没有事务,就新建一个事务。这是最常见的选择。 默认选择

3. Spring配置事务

  • 导包

    导入aspectjweaver包,实现AOP

    <!-- https://mvnrepository.com/artifact/org.aspectj/aspectjweaver -->
    <dependency>
         <groupId>org.aspectj</groupId>
         <artifactId>aspectjweaver</artifactId>
         <version>1.8.13</version>
    </dependency>
    
  • 配置一个事务管理器

    参数需要一个数据源。

    <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <constructor-arg ref="dataSource" />
    </bean>
    
  • 配置声明事务通知

    <!--配置声明事务通知-->
    <tx:advice id="txAdvice" transaction-manager="transactionManager">
        <tx:attributes>
            <!--
            name:哪些方法要使用事务【方法】
            propagation:配置事务的传播特性
            REQUIRED:如果没有事务,就新建一个事务。
            -->
            <tx:method name="add" propagation="REQUIRED"/>
            <tx:method name="delete" propagation="REQUIRED"/>
            <tx:method name="get*" read-only="true"/>
            <tx:method name="*" propagation="REQUIRED"/>
    
        </tx:attributes>
    </tx:advice>
    
  • 配置aop织入事务

    <!--配置aop织入事务,注意点:需要导入织入的包:aspectj-->
    <aop:config>
        <!--切入点-->
        <aop:pointcut id="txPointCut" expression="execution(* org.xiao.dao.UserDaoImpl.*(..))"/>
        <!--通知-->
        <aop:advisor advice-ref="txAdvice" pointcut-ref="txPointCut"/>
    </aop:config>
    

4. 案例

要求:执行一个特定的事务,完成对给定数据库中同时添加和删除用户

分析:事务为添加用户和删除用户

结果预测:添加用户和删除用户,要么都成功,要么都不成功

原始数据库信息为:
在这里插入图片描述

代码部分:

  • 导包

    • mybaits
    • mysql驱动
    • junit
    • spring系列
    • spring-jdbc 【数据源】
    • mybatis-spring整合包
    • aspectjweaver包【事务】
  • 配置文件

    mybatis-config.xml只配置别名和关联映射文件。

    spring配置文件,applicationContext.xml,如下,

    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"
           xmlns:tx="http://www.springframework.org/schema/tx"
           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
           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/tx
            http://www.springframework.org/schema/tx/spring-tx.xsd
            http://www.springframework.org/schema/aop
            http://www.springframework.org/schema/aop/spring-aop.xsd">
    
    
        <!--声明式事务开始-->
        <!--需要配置一个事务管理器,参数需要一个数据源-->
        <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
            <constructor-arg ref="dataSource" />
        </bean>
    
        <!--配置声明事务通知-->
        <tx:advice id="txAdvice" transaction-manager="transactionManager">
            <tx:attributes>
                <!--
                name:哪些方法要使用事务【方法】
                propagation:配置事务的传播特性
                REQUIRED:如果没有事务,就新建一个事务。
                -->
                <tx:method name="add" propagation="REQUIRED"/>
                <tx:method name="delete" propagation="REQUIRED"/>
                <tx:method name="get*" read-only="true"/>
                <tx:method name="*" propagation="REQUIRED"/>
    
            </tx:attributes>
        </tx:advice>
    
        <!--配置aop织入事务,注意点:需要导入织入的包:aspectj-->
        <aop:config>
            <!--切入点-->
            <aop:pointcut id="txPointCut" expression="execution(* org.xiao.dao.UserDaoImpl.*(..))"/>
            <!--通知-->
            <aop:advisor advice-ref="txAdvice" pointcut-ref="txPointCut"/>
        </aop:config>
    
        <!--声明式事务结束-->
    
        <!--1.配置数据源,我们使用的是spring的数据源,还可以使用第三方的数据源
            dbcp,c3p0
            com.mchange.v2.c3p0.ComboPooledDataSource
            org.apache.commons.dbcp.BasicDataSource
        -->
        <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
            <property name="driverClassName" value="com.mysql.jdbc.Driver"/>
            <property name="url" value="jdbc:mysql://localhost:3306/mybatis?useSSL=true&amp;useUnicode=true&amp;characterEncoding=utf-8"/>
            <property name="username" value="root"/>
            <property name="password" value="123456"/>
        </bean>
    
        <!--2.配置SqlSessionFactory-->
        <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
            <property name="dataSource" ref="dataSource" />
            <!--关联mybatis的配置文件-->
            <property name="configLocation" value="classpath:mybatis-config.xml"/>
        </bean>
    
        <!--3.创建selSession-->
        <bean id="sqlSession" class="org.mybatis.spring.SqlSessionTemplate">
            <constructor-arg index="0" ref="sqlSessionFactory" />
        </bean>
    
        <!--4.接口实现类注入sqlSession-->
        <bean id="userDaoImpl" class="org.xiao.dao.UserDaoImpl">
            <property name="sqlSession" ref="sqlSession"/>
        </bean>
    </beans>
    
  • Dao层

    user接口

    package org.xiao.dao;
    
    import org.xiao.pojo.User;
    
    import java.util.List;
    
    public interface UserDao {
    
        //获得全部用户
        List<User> selectUser();
    
        //增加
        int add(User user);
    
        //删除
        int delete(int id);
    
    }
    

    user实现类

    package org.xiao.dao;
    
    import org.xiao.pojo.User;
    import org.mybatis.spring.SqlSessionTemplate;
    
    import java.util.List;
    
    public class UserDaoImpl implements UserDao{
    
        private SqlSessionTemplate sqlSession;
    
        public void setSqlSession(SqlSessionTemplate sqlSession) {
            this.sqlSession = sqlSession;
        }
    
        public List<User> selectUser() {
    
            UserDao mapper = sqlSession.getMapper(UserDao.class);
            User user = new User(5,"李林","sajdlka");
            mapper.add(user);
            mapper.delete(4);
    
            return mapper.selectUser();
    
        }
    
    
        public int add(User user) {
            return 0;
        }
    
        public int delete(int id) {
            return 0;
        }
    
    }
    

    usermapper配置文件

  • 测试类

    public class UserTest {
        @Test
        public void test(){
            ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
    
            UserDao userDaoImpl = (UserDao) context.getBean("userDaoImpl");
            List<User> users = userDaoImpl.selectUser();
        }
    }
    

结果:

事务为删除4号用户并添加5号用户。
在这里插入图片描述

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值