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日

相关文章

  • java实现操作系统中的最佳置换Optimal算法

    Java实现操作系统中的最佳置换Optimal算法攻略 算法介绍 最佳置换算法(Optimal)也称为理论最优算法。其思想是根据还未完成的进程未来的使用情况,计算出每一个进程在什么时候会访问页面,然后选择最长时间以后才用到的页面进行置换。 实现步骤 首先根据需要分配的内存大小,将所有的物理块置为空闲状态,并初始化所有页面的最近使用时间为正无穷大。 当一个新页…

    Java 2023年5月19日
    00
  • SpringBoot Starter机制及整合tomcat的实现详解

    下面我将详细讲解“SpringBoot Starter机制及整合tomcat的实现详解”。 SpringBoot Starter机制 什么是Starter? 在Spring Boot中,Starter是指用于快速启动某一技术栈的依赖包,通过引入Starter,开发人员可以非常方便地引入一整套封装好的技术栈。 例如,我们想要应用JDBC来实现数据库操作,只需要…

    Java 2023年5月19日
    00
  • 一文详解Java如何创建和销毁对象

    一文详解Java如何创建和销毁对象 1. 对象创建 在Java中,我们可以使用new关键字创建对象,并且可以通过构造器来对对象进行初始化。以下是一个示例: public class Person{ private String name; private int age; public Person(String name, int age){ this.n…

    Java 2023年5月26日
    00
  • Struts2中图片以base64方式上传至数据库

    下面是“Struts2中图片以base64方式上传至数据库”的完整攻略及两个示例。 1.准备工作 在开始具体操作前,我们需要先进行一些准备工作: 引入Struts2、Hibernate以及相关依赖库 使用Hibernate框架进行数据库操作 配置Struts2的multipartInterceptor,以实现文件上传功能 编写数据库表及实体类,以后面进行存储…

    Java 2023年5月20日
    00
  • MyBatis的逆向工程详解

    MyBatis的逆向工程详解 什么是MyBatis逆向工程? MyBatis逆向工程是指根据数据库中的表结构生成MyBatis对应的Mapper接口以及对应的Mapper XML文件。如果手写这些代码,需要考虑很多细节,编写起来比较繁琐和容易出错,而逆向工程则可以自动化地生成这些代码。逆向工程可以大大提高开发效率,并且保证生成的代码的准确性。 MyBatis…

    Java 2023年5月19日
    00
  • 2023年4月21日-关于远程feign调用实现文件上传下载

    一、客户需求:做一个查询程序,客户提供一个excel模板,将查询结果保存到excel模板中,上传到文件服务,供客户下载使用。 二、代码实现 // 服务A,文件上传 @ApiOperation(“上传文件-demo”) @PostMapping(value = “/uploadDemo/{busType}/{billId}”) public ResBean u…

    Java 2023年4月22日
    00
  • java(jsp)整合discuz同步登录功能详解

    下面是详细讲解“java(jsp)整合discuz同步登录功能详解”的攻略。 介绍 Discuz是一个比较古老的论坛系统,它有很多的功能以及插件,而且也有很多网站在使用它。如果你已经有了一个成熟的Java Web网站,那么也许你希望这个网站能够跟Discuz集成起来,实现同步登录的功能。这篇攻略将介绍如何实现Java Web和Discuz之间的同步登录功能。…

    Java 2023年6月15日
    00
  • MybatisPlus如何处理Mysql的json类型

    下面是MybatisPlus如何处理MySQL的Json类型的攻略: 背景 MySQL从5.7开始支持Json类型。对于Java开发者来说,通常使用json字符串表示json类型的数据。在开发过程中,可能需要把json字符串映射成Java对象并进行持久化或者把Java对象转换成json字符串进行传输。在使用MybatisPlus做ORM开发时,可以通过使用@…

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