Spring声明式事务配置使用详解

Spring声明式事务配置使用详解

什么是事务

事务是一组完整的业务操作,这些操作作为一个原子单元,要么全部成功,要么全部失败回滚,保证数据库中的数据一致性。

声明式事务的优点

Spring框架提供的声明式事务管理有以下几个好处:

  1. 代码简洁:通过使用声明式事务管理,Spring框架可以将所有的数据库事务处理的代码都放在配置文件中,这样就不需要在业务逻辑代码中手动控制事务的开启、提交或回滚事务的操作。

  2. 不受编程语言的限制:不管是Java还是其他任何支持AOP的编程语言,都可以使用Spring框架提供的声明式事务管理服务。这就意味着,只要是符合AOP的编程语言,都可以使用Spring框架提供的事务管理服务。

  3. 无代码侵入:使用声明式事务管理的好处之一是它不会对业务逻辑产生任何影响,因此,业务逻辑代码与事务管理的代码可以很好地分离。在这种情况下,业务逻辑代码可以集中在处理业务逻辑方面,而事务管理的代码可以集中在单独的配置文件中。

Spring声明式事务配置

Spring提供了两种方式实现声明式事务:

  1. 基于XML的声明式事务:该方式使用XML配置文件来配置声明式事务。

  2. 基于注解的声明式事务:该方式使用注解来配置声明式事务。

本文将介绍基于XML的声明式事务配置。

配置Spring声明式事务

配置事务管理器

在使用Spring声明式事务之前,必须先配置事务管理器,配置方式如下:

<!--配置事务管理器-->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
    <property name="dataSource" ref="dataSource"/>
</bean>

其中,transactionManager是事务管理器的id,class指定了使用的事务管理器类,这里使用的是DataSourceTransactionManager类,这是一个基于DataSource的事务管理器,property设置了dataSource属性,这里的dataSource是数据源的id,我们需要在该配置文件中提前定义。

配置数据源

在配置事务管理器时,需要指定使用的数据源,因此,需要在配置文件中提前配置数据源。数据源的配置方式因你所使用的具体数据源而异。在这里,我们演示使用Apache的Commons DBCP数据源的配置方式。以下是数据源配置的一些示例代码:

<!--数据库驱动-->
<bean id="driverManagerDataSource" class="org.apache.commons.dbcp2.BasicDataSource" destroy-method="close">
    <property name="driverClassName" value="com.mysql.jdbc.Driver" />
    <property name="url" value="jdbc:mysql://localhost:3306/mydatabase?serverTimezone=UTC&amp;useSSL=false" />
    <property name="username" value="myusername" />
    <property name="password" value="mypassword" />
    <property name="initialSize" value="5" /> <!--初始化连接数-->
    <property name="maxIdle" value="10" /> <!--最大空闲连接-->
    <property name="maxTotal" value="100" /> <!--最大连接数量-->
    <property name="removeAbandonedOnBorrow" value="true" /> <!--连接过期是否自动回收-->
</bean>

<bean id="dataSource" class="org.springframework.jdbc.datasource.LazyConnectionDataSourceProxy">
    <property name="targetDataSource" ref="driverManagerDataSource"/>
</bean>

在上面的代码中,我们首先定义了一个Commons DBCP数据源,并指定了驱动类、URL、用户名和密码等参数。该数据源配置完成后,使用org.springframework.jdbc.datasource.LazyConnectionDataSourceProxy类包装数据源,将数据源设置为"targetDataSource"属性。

配置DAO

DAO层是访问数据库的一个封装层,需要在DAO中调用通过事务提交的代码。因此,在DAO中,必须使用Spring提供的JdbcTemplate类来使用Spring声明式事务。以下是一个DAO示例:

public class UserDAO {
    private JdbcTemplate jdbcTemplate;

    public void setDataSource(DataSource dataSource) {
        this.jdbcTemplate = new JdbcTemplate(dataSource);
    }

    //添加用户
    public int addUser(User user) {
        String sql = "INSERT INTO user(username,password,age) VALUES (?,?,?)";
        return this.jdbcTemplate.update(sql, new Object[] { user.getUsername(), user.getPassword(), user.getAge() });
    }
}

在上面的代码中,我们在UserDAO类中使用Spring提供的JdbcTemplate类与数据源进行交互,并使用其中提供的update方法提交SQL语句。

配置Spring声明式事务

现在,我们已经配置好了事务管理器、数据源和DAO。下面,我们来配置Spring声明式事务。事务配置方式如下:

<!--声明式事务配置-->
<tx:advice id="txAdvice" transaction-manager="transactionManager">
    <tx:attributes>
        <tx:method name="add*" propagation="REQUIRED" />
        <tx:method name="update*" propagation="REQUIRED" />
        <tx:method name="delete*" propagation="REQUIRED" />
        <tx:method name="*" propagation="REQUIRED" read-only="true" />
    </tx:attributes>
</tx:advice>

<!--事务设置-->
<aop:config>
    <aop:pointcut id="allMethod" expression="execution(* com.example.*.*DAO.*(..))" />
    <aop:advisor advice-ref="txAdvice" pointcut-ref="allMethod" />
</aop:config>

其中,aop:config标签用来定义切入点和通知类型,这里的pointcut表示对所有DAO类中的全部方法进行拦截,通知类型为传播方式为REQUIRED的声明式事务管理。在这里,我们定义了四种类型的拦截方式:

  1. 对add、update、delete*三类方法进行事务管理,传播方式为REQUIRED。

  2. 对所有方法进行事务管理,传播方式为REQUIRED,同时设置readOnly为true,表示只读性质事务。

声明式事务使用示例

在上面的配置完成后,我们可以进行事务间的开启、提交和回滚操作,以下是几个使用示例。

1. 添加用户(事务成功)

//创建用户DAO
UserDAO userDAO = new UserDAO();
userDAO.setDataSource(dataSource);

//新建事务
DefaultTransactionDefinition transDefinition = new DefaultTransactionDefinition();
TransactionStatus status = transactionManager.getTransaction(transDefinition);
try {
    //业务操作
    User newUser = new User();
    newUser.setUsername("testuser");
    newUser.setPassword("testpassword");
    newUser.setAge(18);

    int result = userDAO.addUser(newUser);

    System.out.println("添加用户:" + result);

    //提交事务
    transactionManager.commit(status);
} catch (Exception e) {
    //回滚事务
    transactionManager.rollback(status);
    e.printStackTrace();
}

在上面的示例中,我们使用transactionManager开启一个事务,并定义一个TransactionStatus对象status,用于管理事务的状态。此后,我们使用DAO类添加一个新用户,当添加完成后,使用事务管理器对该事务进行提交。

2. 添加用户(事务失败)

//创建用户DAO
UserDAO userDAO = new UserDAO();
userDAO.setDataSource(dataSource);

//新建事务
DefaultTransactionDefinition transDefinition = new DefaultTransactionDefinition();
TransactionStatus status = transactionManager.getTransaction(transDefinition);
try {
    //业务操作
    User newUser = new User();
    newUser.setUsername("testuser");
    newUser.setPassword("testpassword");
        newUser.setAge(200); //年龄不合法,导致事务失败

    int result = userDAO.addUser(newUser);

    System.out.println("添加用户:" + result);

    //提交事务
    transactionManager.commit(status);
} catch (Exception e) {
    //回滚事务
    transactionManager.rollback(status);
    e.printStackTrace();
}

在上面的示例中,我们使用transactionManager开启一个事务,并定义一个TransactionStatus对象status,用于管理事务的状态。此后,我们使用DAO类添加一个新用户,当添加完成后,使用事务管理器对该事务进行提交。由于该用户年龄属性不合法,此时事务将失败,会回滚数据。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Spring声明式事务配置使用详解 - Python技术站

(0)
上一篇 2023年5月20日
下一篇 2023年5月20日

相关文章

  • Springboot集成Kafka进行批量消费及踩坑点

    下面我来详细讲解“Springboot集成Kafka进行批量消费及踩坑点”的完整攻略。 一、前言 Kafka是一款分布式消息队列系统,由Apache在2011年引入,其主要包括了生产者、消费者等API,用于实现消息的发送和接收等操作。而Springboot则是目前流行的一种开发框架,它可以简化Java应用的开发过程。本文将探讨如何在Springboot中集成…

    Java 2023年5月20日
    00
  • SpringMVC4+MyBatis+SQL Server2014实现数据库读写分离

    下面是关于“SpringMVC4+MyBatis+SQL Server2014实现数据库读写分离”的完整攻略,包含两个示例说明。 SpringMVC4+MyBatis+SQL Server2014实现数据库读写分离 在本文中,我们将介绍如何使用SpringMVC4和MyBatis实现数据库读写分离,以提高系统的性能和可靠性。 步骤1:添加依赖 首先,我们需要…

    Java 2023年5月17日
    00
  • Java8中字符串处理库strman-java的使用示例

    针对Java8中字符串处理库strman-java的使用示例,我可以提供以下完整攻略: 一、什么是strman-java strman-java是一个Java8中的字符串处理库,该库提供了各种字符串处理方法,例如字符串分割、替换、格式化、加密、解码等。同时,该库支持链式调用,可用于流畅地处理字符串,方便简洁。strman-java库基于Node.js中的un…

    Java 2023年5月27日
    00
  • 你知道将Bean交给Spring容器管理有几种方式(推荐)

    将Bean交给Spring容器管理的方式 在Spring中,我们可以将Bean交给Spring容器管理,从而实现依赖注入和控制反转。下面是将Bean交给Spring容器管理的几种方式。 1. 使用@Component注解 @Component是Spring中最常用的注解之一,用于将一个类声明为Bean,并交给Spring容器管理。下面是一个简单的示例: @C…

    Java 2023年5月18日
    00
  • jQuery老黄历完整实现方法

    jQuery老黄历完整实现方法 简介 jQuery老黄历是一款对于时间的格式化呈现的插件,可以生成比较形象化的日期解释,比如”今天是个好日子,宜开发,宜部署”。 完整实现方法 要实现jQuery老黄历的功能,需要完成以下步骤: 步骤1:引入jQuery和老黄历脚本 首先,需要在HTML文件的<head>标签内引入jQuery和老黄历的脚本: &l…

    Java 2023年5月23日
    00
  • java 使用ElasticSearch完成百万级数据查询附近的人功能

    下面是详细的“java 使用ElasticSearch完成百万级数据查询附近的人功能”的攻略: 一、准备工作 1. 安装Elasticsearch 首先需要在本地安装Elasticsearch,可以到官方网站下载并安装。也可以使用Docker进行安装。 2. 安装Elasticsearch客户端 在Java代码中使用Elasticsearch,需要引入Ela…

    Java 2023年5月20日
    00
  • Spring Cloud Feign 自定义配置(重试、拦截与错误码处理) 代码实践

    下面是关于“Spring Cloud Feign 自定义配置(重试、拦截与错误码处理)”的完整攻略详情。 1. 什么是 Spring Cloud Feign Spring Cloud Feign 是一个声明式 REST 客户端,它使通过 HTTP 通信的服务调用变得更加简单。 Feign 会通过定义接口的方式来注入需要访问的远程服务,这样就可以像调用本地方法…

    Java 2023年5月20日
    00
  • 浅谈Java抽象类和接口的个人理解

    浅谈Java抽象类和接口的个人理解 Java是一门面向对象编程语言,面向对象编程的三大特性是封装、继承和多态。抽象类和接口都是Java中体现多态的机制。 抽象类 抽象类是不能被实例化的类,它通常被用于抽象出多个类中的共性并定义出它们的方法名、参数列表、返回类型和访问类型,由其子类来实现这些方法。 抽象类的定义方式为: public abstract clas…

    Java 2023年5月20日
    00
合作推广
合作推广
分享本页
返回顶部