首页 > 其他分享 >Spring基础使用八

Spring基础使用八

时间:2022-11-01 20:46:50浏览次数:52  
标签:事务 org Spring Transactional 基础 回滚 springframework 使用 import

Spring基础使用八

基于注解的声明式事务

Spring提供了@Transactional注解实现事务管理

配置@Transactional

  1. 配置Spring的xml
<?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: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 https://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd">

<!--扫描组件-->
<context:component-scan base-package="com.wfy"></context:component-scan>
<!-- 导入jdbc.properties-->
    <context:property-placeholder location="jdbc.properties"></context:property-placeholder>
<!-- 创建数据源-->
    <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
        <property name="driverClassName" value="${jdbc.driver}"></property>
        <property name="url" value="${jdbc.url}"></property>
        <property name="username" value="${jdbc.username}"></property>
        <property name="password" value="${jdbc.password}"></property>
    </bean>
    <bean class="org.springframework.jdbc.core.JdbcTemplate">
        <property name="dataSource" ref="dataSource"></property>
    </bean>

<!--配置事务管理器-->
    <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="dataSource"></property>
    </bean>
        <!--
        开启事务驱动注解
        将使用@Translational注解所标识的方法或类中所有的方法使用事务进行管理
        transaction-manager属性设置事务管理器的id
        若事务管理器的bean的id默认为transactionManager,则该属性可以默认不写
        -->
    <tx:annotation-driven transaction-manager="transactionManager"/>
</beans>

事务管理:

通过tx:annotational-driven元素配置事务注解驱动,tx:annotational-driven元素中有一个常用属性transactional-manager,该属性用于指定事务管理器

<!--配置事务管理器-->
    <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="dataSource"></property>
    </bean>
        <!--
        开启事务驱动注解
        将使用@Translational注解所标识的方法或类中所有的方法使用事务进行管理
        transaction-manager属性设置事务管理器的id
        若事务管理器的bean的id默认为transactionManager,则该属性可以默认不写
        -->
    <tx:annotation-driven transaction-manager="transactionManager"/>
  1. 在service层使用@Transactional注解
package com.wfy.service.impl;

import com.wfy.dao.BookDao;
import com.wfy.service.BookService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

@Service
public class BookServiceImpl implements BookService {

    @Autowired
    private BookDao bookDao;
    @Override
    @Transactional
    public void buyBook(Integer userId, Integer bookId) {
        //查询图书的价格
      Integer price=  bookDao.getPriceById(bookId);
        //更新图书的库存
        bookDao.updateBook(bookId);
        //更新用户的余额
        bookDao.updateBalance(userId,price);
    }
}
  1. 测试案例
package com.wfy.spring.test;

import com.wfy.controller.BookController;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:tx-annotation.xml")
public class TxByAnnotation {

    /**声明式事务的配置步骤:
     * 1.在Spring的配置文件中配置事务管理器
     * 2.开启事务的注解驱动
     *在需要被事务管理的方法上,添加@Transactional注解,该方法就会被事务管理
     * @Transactional注解标识的位置:
     * 1.标识在方法上
     * 2.标识在类上,则类中所有的方法都会被事务管理
     */
    @Autowired
    private BookController bookController;
    @Test
    public void testByBook(){
        bookController.buyBook(1,1);
    }
}

只有当声明的事务中的所有方法全部执行,数据才会更新

声明式事务的属性

  • 只读
 @Transactional(readOnly = true)

如果对增删改操作设置只读,则会报以下错误:

Caused by: java.sql.SQLException: Connection is read-only. Queries leading to data modification are not allowed

  • 超时
  @Transactional(timeout = 3    )

超时则会报以下错误:

org.springframework.transaction.TransactionTimedOutException: Transaction timed out: deadline was Tue Nov 01 19:20:14 CST 2022

事务在执行过程中,有可能因为遇到某些问题,导致程序卡住,从而长时间占用数据库资源。此时程序很可能会出现问题,出现问题的程序应该会被回滚,撤销它已做的操作,事务结束,把资源让出来,让其他正常程序可以执行。

超时回滚,释放资源

  • 回滚策略

声明式事务默认只针对运行时异常回滚,编译时异常不回滚。

    @Transactional(noRollbackFor =ArithmeticException.class    )

用于指定不会导致事务回滚的异常类数组

  @Transactional(noRollbackForClassName = "java.lang.ArithmeticException")

用于指定不会导致事务回滚的异常类数组名称

  @Transactional(RollbackFor)

用于指定导致事务回滚的异常类数组

  @Transactional(RollbackForClassName)

用于指定导致事务回滚的异常类数组名称

  • 事务隔离级别

数据库系统必须具有隔离并发运行各个事务的能力,使它们不会相互影响,避免各种并发问题。一个事务与其他事务隔离的程度称为隔离级别。SQL标准中规定了各种事务隔离级别,不同隔离级别对应不同的干扰程度,隔离级别越高,数据一致性就越好,但并发性越弱。

  @Transactional( isolation = Isolation.DEFAULT)

用于指定事务的隔离级别

  • 传播行为
 @Transactional(propagation = Propagation.REQUIRED)

默认情况,表示如果当前线程上有已经开启的事务可用,那么就在这个事务中运行。

  @Transactional( propagation = Propagation.REQUIRES_NEW)

表示不管当前线程上是否有已经开启的事务,都要开启新事务。

基于XML的声明式事务

配置Spring的xml文件

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

    <!--扫描组件-->
    <context:component-scan base-package="com.wfy"></context:component-scan>
    <!-- 导入jdbc.properties-->
    <context:property-placeholder location="jdbc.properties"></context:property-placeholder>
    <!-- 创建数据源-->
    <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
        <property name="driverClassName" value="${jdbc.driver}"></property>
        <property name="url" value="${jdbc.url}"></property>
        <property name="username" value="${jdbc.username}"></property>
        <property name="password" value="${jdbc.password}"></property>
    </bean>
    <bean class="org.springframework.jdbc.core.JdbcTemplate">
        <property name="dataSource" ref="dataSource"></property>
    </bean>

    <!--配置事务管理器-->
    <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="dataSource"></property>
    </bean>
<!-- 配置事务通知-->
      <tx:advice id="tx" transaction-manager="transactionManager">
          <tx:attributes>
              <tx:method name="buyBook"/>
          </tx:attributes>
      </tx:advice>

    <aop:config>
        <aop:advisor advice-ref="tx" pointcut="execution(* com.wfy.service.impl.*.*(..))"></aop:advisor>
    </aop:config>
</beans>

配置文件:

    <!--配置事务管理器-->
    <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="dataSource"></property>
    </bean>
<!-- 配置事务通知-->
      <tx:advice id="tx" transaction-manager="transactionManager">
          <tx:attributes>
              <tx:method name="buyBook"/>
          </tx:attributes>
      </tx:advice>

    <aop:config>
        <aop:advisor advice-ref="tx" pointcut="execution(* com.wfy.service.impl.*.*(..))"></aop:advisor>
    </aop:config>

注意:基于xml实现的声明式事务,必须引入aspectJ的依赖

<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-aspects</artifactId>
    <version>5.3.23</version>
</dependency>

标签:事务,org,Spring,Transactional,基础,回滚,springframework,使用,import
From: https://www.cnblogs.com/wfy-studying/p/16849067.html

相关文章

  • SpringMVC源码-创建ContentNegotiationManagerFactoryBean
    一、ContentNegotiationManagerFactoryBean的BeanDifinition及实现的接口上图的属性说的是ContentNegotiationManagerFactoryBean对应的BeanDifinition中设置的属性,需要......
  • 关于Markdown语法的入门学习与使用
    Markdown介绍(百度扒的)Markdown是一种轻量级标记语言,创始人为约翰·格鲁伯(JohnGruber)。它允许人们使用易读易写的纯文本格式编写文档,然后转换成有效的XHTML(或者HTML)文......
  • SpringMVC-mvc context重载AbstractApplicationContext.refresh方法部分
    一、postProcessBeanFactory(ConfigurableListableBeanFactorybeanFactory)AbstractRefreshableWebApplicationContext.postProcessBeanFactory(ConfigurableListableBea......
  • 保留参数的概念和使用场景
    什么是保留参数(reservedparameter)某些API函数的部分参数要求调用者必须传入指定的固定值,且这些参数名中通常带reserved字样。一般来说,调用者不遵守此约定会导致调用......
  • Spring入门
    一、Spring概述介绍Spring框架是一个开源的Java平台,它最初是由RodJohnson编写的,并且于2003年6月首次在Apache2.0许可下发布。Spring是轻量级的框架,其基......
  • 在Vue中使用Swiper轮播图、同时解决点击轮播图左右切换按钮不生效的问题、同时将轮播
    轮播图左右的切换按钮、如果点击没有反应,控制台也没有报错。很大可能是==版本问题==。如果不指定版本信息、默认安装的是最新的版本。版本过高或者过低都有可能导致无效。......
  • Springboot 项目打成jar包部署到服务器中的方式
    Springboot项目打成jar包部署到服务器中的方式前言:目前,前后端分离的架构已成主流,而使用SpringBoot构建Web应用是非常快速的,项目发布到服务器上的时候,只需要打成一个jar包......
  • Win11 使用Hyper-V快速安装Win10
    由于我的电脑更新成了win11,很多东西还不如win10找了半天没有找到hyper-v,于是就搜索记录一下过程过程安装hyper-v打开新建一个Hyper-V.cmd文件,将下面的内容粘入保存。......
  • springCloud分布式框架搭建教程
    集群:指一个项目部署在不同的服务器,通过负载均衡来访问,形成集群。分布式:指项目中不同的模块可以独立运行。 Springboot是什么?是推出解决传统框架配置文件繁杂冗余,基于maven......
  • SpringBoot集成微信支付0.4.7版本
    1.引入maven依赖<!--wechat支付--><dependency><groupId>com.github.wechatpay-apiv3</groupId><artifactId>wechatpay-ap......