Spring超详细讲解事务

Spring超详细讲解事务

什么是事务

事务是指一个操作序列,该操作序列中的所有操作都必须全部执行成功或全部执行失败。事务支持保证数据库的一致性、完整性和隔离性。

Spring事务的优点

在使用Spring进行数据库操作时,使用Spring事务能够带来以下优点:

  • Spring事务对所有的数据库访问代码提供了一致的编程模型
  • Spring事务可以将数据库事务的边界引入到不同的服务方法之间,而不是只在单个服务方法中使用
  • Spring事务提供了面向切面编程的方式来声明性地管理事务。这使得开发人员不必在业务逻辑中编写事务代码

Spring事务类型

Spring事务支持以下类型:

  • 编程式事务:通过编写代码来管理事务
  • 声明式事务:通过配置声明式事务管理器来管理事务

声明式事务是比较常用的一种方式,因为它可以通过配置来管理事务而不需要编写大量的重复代码。

Spring声明式事务的配置

要使用声明式事务,需要完成以下步骤:

  1. 配置数据源

<bean id="dataSource" class="org.apache.commons.dbcp2.BasicDataSource">
<property name="driverClassName" value="com.mysql.cj.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/test"/>
<property name="username" value="root"/>
<property name="password" value="123456"/>
<property name="initialSize" value="5"/>
<property name="maxTotal" value="10"/>
</bean>

  1. 配置事务管理器

<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"/>
</bean>

  1. 配置基于注解的声明式事务

<tx:annotation-driven transaction-manager="transactionManager"/>

以上配置需要在Spring配置文件中进行。

Spring事务的注解

  • @Transactional:用于声明一个方法是事务方法,即该方法执行过程中如果出现异常会进行事务回滚。

  • @Transactional(propagation=Propagation.REQUIRED):如果当前方法正在一个事务中运行,那么这个事务将被继续使用,而不是重新开启一个新的事务。如果当前方法没有在一个事务中运行,那么这个方法将会开启一个新的事务。

  • @Transactional(propagation=Propagation.REQUIRES_NEW):该方法必须开启一个新的事务。如果当前方法已经在一个事务中运行,那么当前事务将被挂起,新的事务将被开启。

Spring事务示例

示例1:使用注解管理事务

创建一个UserService接口和一个UserServiceImpl类:

public interface UserService {
    List<User> findAll();
    void transfer(int fromId, int toId, double money);
}

@Service
public class UserServiceImpl implements UserService {

    @Autowired
    private UserDao userDao;

    @Override
    public List<User> findAll() {
        return userDao.findAll();
    }

    @Override
    @Transactional(propagation=Propagation.REQUIRED)
    public void transfer(int fromId, int toId, double money) {
        userDao.update(fromId, -money);
        int i = 1/0; // 抛出异常
        userDao.update(toId, money);
    }
}
  • 使用@Autowired注解进行依赖注入;
  • 使用@Transactional注解声明transfer方法是事务方法;
  • 在transfer方法中模拟转账操作,如果在转账过程中发生异常,就会进行事务回滚。

示例2:使用XML配置管理事务

创建一个UserService接口和一个UserServiceImpl类:

public interface UserService {
    List<User> findAll();
    void transfer(int fromId, int toId, double money);
}

@Service
public class UserServiceImpl implements UserService {

    @Autowired
    private UserDao userDao;

    @Override
    public List<User> findAll() {
        return userDao.findAll();
    }

    @Override
    public void transfer(int fromId, int toId, double money) {
        userDao.update(fromId, -money);
        int i = 1/0; // 抛出异常
        userDao.update(toId, money);
    }
}
  • 使用@Autowired注解进行依赖注入。

创建一个UserDao类:

@Repository
public class UserDao {

    @Autowired
    private JdbcTemplate jdbcTemplate;

    public List<User> findAll() {
        return jdbcTemplate.query("SELECT * FROM user", new BeanPropertyRowMapper<>(User.class));
    }

    public void update(int id, double money) {
        jdbcTemplate.update("UPDATE user SET balance=balance+? WHERE id=?", money, id);
    }
}
  • 使用@Autowired注解进行依赖注入;
  • 使用JdbcTemplate进行数据库操作。

在Spring配置文件中进行以下配置:

    <bean id="dataSource" class="org.apache.commons.dbcp2.BasicDataSource">
        <property name="driverClassName" value="com.mysql.cj.jdbc.Driver"/>
        <property name="url" value="jdbc:mysql://localhost:3306/test"/>
        <property name="username" value="root"/>
        <property name="password" value="123456"/>
        <property name="initialSize" value="5"/>
        <property name="maxTotal" value="10"/>
    </bean>

    <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
        <property name="dataSource" ref="dataSource"/>
    </bean>

    <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="dataSource"/>
    </bean>

    <bean id="userDao" class="com.example.demo.dao.UserDao">
        <property name="jdbcTemplate" ref="jdbcTemplate"/>
    </bean>

    <bean id="userService" class="com.example.demo.service.impl.UserServiceImpl">
        <property name="userDao" ref="userDao"/>
    </bean>

    <tx:advice id="txAdvice" transaction-manager="transactionManager">
        <tx:attributes>
            <tx:method name="*"/>
        </tx:attributes>
    </tx:advice>

    <aop:config>
        <aop:pointcut id="userServicePointcut" expression="execution(* com.example.demo.service.UserService.*(..))"/>
        <aop:advisor advice-ref="txAdvice" pointcut-ref="userServicePointcut"/>
    </aop:config>
  • 配置数据源、JdbcTemplate、事务管理器、UserDao、UserService;
  • 配置事务增强和切入点。

总结

本篇文章介绍了Spring事务的概念、优点、类型和注解,以及如何使用注解和XML配置管理事务,并提供了两个示例。使用Spring事务能够使代码更简洁、更规范化、更易于维护,提高代码质量和开发效率。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Spring超详细讲解事务 - Python技术站

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

相关文章

  • Go Java算法之简化路径实例详解

    Go Java算法之简化路径实例详解 本篇文章将详细讲解如何使用Go和Java算法来简化路径。首先,我们需要了解路径简化的定义和目的。 什么是路径简化? 路径简化是将路径中冗余的部分删除,使其变得更短、更干净、更易读。例如,路径”/a/b/c/../d”可以简化为”/a/b/d”。这不仅可以节省存储空间,还可以提高代码的效率。 路径简化的目的 路径简化有多种…

    Java 2023年5月19日
    00
  • Java Apache Commons报错“InterruptedIOException”的原因与解决方法

    当使用Java的Struts框架时,可能会遇到“ActionServletMappingException”错误。这个错误通常由以下原因之一起: ActionServlet配置错误:如果ActionServlet配置错误,则可能会出现此错误。在这种情况下,需要检查ActionServlet配置以解决此问题。 ActionServlet无效:如果ActionS…

    Java 2023年5月5日
    00
  • 浅谈JAVA 线程状态中可能存在的一些误区

    浅谈JAVA 线程状态中可能存在的一些误区 简介 JAVA 线程状态是指线程对象在运行过程中所处的状态。在JAVA中,线程有6种状态,分别是新建状态、就绪状态、运行状态、阻塞状态、等待状态和结束状态。然而,对于线程状态,有一些误解是非常普遍的。本文将深入浅出地解释这些问题并给出解决方案。 误区一:线程的唤醒一定要使用notify而不能使用notifyAll …

    Java 2023年5月18日
    00
  • Java复制(拷贝)数组的4种方法:arraycopy()方法、clone() 方法、copyOf()和copyOfRan

    当我们需要在Java中复制(拷贝)数组时,有四种主要的方法可供选择: 使用arraycopy()方法 使用clone()方法 使用copyOf()方法 使用copyOfRange()方法 下面,我们将详细讲解这四种方法。 1. 使用arraycopy()方法 public static void arraycopy(Object src, int srcPo…

    Java 2023年5月26日
    00
  • 详解Java生成PDF文档方法

    详解Java生成PDF文档方法 介绍 在Java中,我们可以使用各种工具库来生成PDF文档。本文将详细讲解如何使用iText和PDFBox库来生成PDF文档。 iText库 iText是一款Java库,可以用来创建和操作PDF文档。它提供了许多方法和类来生成、操作和处理PDF内容。以下是一个简单的示例。 首先,需要引入iText库的maven依赖。 <…

    Java 2023年5月19日
    00
  • 基于SpringMVC实现网页登录拦截

    基于SpringMVC实现网页登录拦截 本文将详细讲解如何使用SpringMVC实现网页登录拦截,并提供两个示例说明。 环境准备 在开始实现网页登录拦截之前,我们需要准备以下环境: JDK 18或以上版本 Maven 3.6.3或以上版本 Tomcat 9.0或以上版本 实现步骤 下面是实现网页登录拦截的详细步骤: 步骤一:创建Maven项目 首先,我们需要…

    Java 2023年5月17日
    00
  • 易语言实现163邮箱登录获取邮件列表等操作的代码

    首先,易语言是一种面向过程的编程语言,可以通过WinAPI调用实现各种功能。要实现163邮箱登录获取邮件列表等操作,需要先了解163邮箱的登录流程和相关API接口。 一、登录流程1. 用户输入邮箱地址和密码;2. 向服务器发送登录请求,并携带邮箱地址和密码;3. 服务器验证邮箱地址和密码,返回登录结果;4. 如果登录成功,服务器返回登录凭证(Cookie);…

    Java 2023年6月15日
    00
  • java通过实例了解值传递和引用传递

    首先,需要理解Java中两种数据类型传递方式:值传递和引用传递。值传递是指在方法调用时传递的是实际的值,而引用传递则是指传递的是对象的引用。 值传递(Value Passing) Java中的基本数据类型,如int、float、boolean等都是通过值传递的方式进行传递。这意味着,当你将一个基本数据类型作为参数传递给一个方法时,它会复制参数的值,并将其传递…

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