百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 技术教程 > 正文

Spring 16: SM(Spring + MyBatis) 注解式事务 与 声明式事务

mhr18 2025-02-20 16:52 21 浏览 0 评论

Spring事务处理方式

方式1:注解式事务

  • 使用@Transactional注解完成事务控制,此注解可添加到类上,则对类中所有方法执行事务的设定,注解添加到方法上,则对该方法执行事务处理
  • @Transactional(...)注解参数说明:
    • propagation = Propagation.REQUIRED:设置事务的传播特性,例如当多个事务叠加时,谁起主导作用等
    • noRollbackForClassName = "异常名称":指定发生什么异常不回滚,使用的是异常的名称
    • noRollbackFor = 异常.class:指定发生什么异常不回滚,使用的是异常的类型
    • rollbackForClassName = "异常名称":指定发生什么异常必须回滚,使用的是异常的名称
    • rollbackFor = 异常.class:指定发生什么异常必须回滚,使用的是异常的类型:
    • timeout = -1:连接超时设置,默认值是-1,表示永不超时
    • readOnly = false:默认为false,如果是查询操作,必须设置为true
    • isolation = Isolation.DEFAULT:使用的数据库的默认隔离级别
  • 注意:当一个类中有较多方法时,对方法进行一对一的注解式事务管理太多繁琐,简单演示事务特性时可以使用注解式事务,在实际项目中不常用

方式2:声明式事务

  • 在配置文件中添加一次,整个项目遵循该事务的设定,是Spring常用的,也是非常有名的事务处理方式
  • 要求项目中的方法命名有规范,例如:
  • 添加操作方法名包含:add,save,insert,set等单词
  • 更新操作方法名包含:update,change,modify等单词
  • 删除操作方法名包含:delete,drop,remove,clear等单词
  • 查询操作方法名包含:select,find,search,get等单词
  • 上述规范的原因:为了配置事务切面时,可以使用通配符来匹配满足通配条件的方法

声明式事务案例

applicationContext_trans.xml

  • 在src/main/resources目录下新建applicationContext_trans.xml,注意:这里如果使用idea默认的xml头信息,< tx >标签的属性显示不出来,可以使用下面的头信息





        
        

        
        

        
        
            
        

        
        
            
                
                
                
                
                
                
                
                
                
                
                
                
                
            
        

        
        
            
            

            
            
        

业务实现类

  • 修改UserServiceImpl:持有Account业务逻辑层的接口类型的变量,在User业务逻辑中嵌套调用Account业务
package com.example.service.impl;


import com.example.mapper.UserMapper;
import com.example.pojo.Account;
import com.example.pojo.User;
import com.example.service.AccountService;
import com.example.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

/**
 * 业务实现类
 */
@Service
public class UserServiceImpl implements UserService {
    //业务逻辑层实现类持有数据访问层的接口类型的变量
    @Autowired
    UserMapper userMapper;

    //持有Account业务逻辑层的接口类型的变量
    @Autowired
    AccountService accountService;

    @Override
    public int insert(User user) {
        int num = userMapper.insert(user);
        if(num == 1){
            System.out.println("用户导入成功!");
        }else{
            System.out.println("用户导入失败!");
        }
        
        //嵌套调用账户的业务逻辑功能
        accountService.save(new Account(25, "荷包蛋6","富婆的账户6"));
        return num;
    }
}

测试

package com.example.test;

import com.example.pojo.User;
import com.example.service.UserService;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class TestUserAndAccount {
    @Test
    public void testUserAndAccount(){
        //创建Spring容器
        ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext_trans.xml");
        //获取用户的业务逻辑层对象
        UserService userService = (UserService) ac.getBean("userServiceImpl");
        //调用业务功能
        userService.insert(new User(2, "荷包蛋2", "hanzhanghan2"));
    }
}

测试输出

  • 从控制台看出两个业务的sql语句都执行成功,程序在出错后终止
  • 在上述事务配置下,用户业务和账户业务都被添加事务,从用户表和账户表可以看出,在内部嵌套的业务执行失败后,两个事务都被撤销,两条记录都未成功导入

修改aplicationContext_trans.xml

  • 对下述两个标签添加新的标签属性,对于某些指定异常不回滚


测试输出

  • 这时对于算术异常不进行事务回滚,再次测试,两条记录成功导入数据表并有效保存

注意

如果当声明式注解所规划的事务管理和某个业务层的业务方法对事务的个性化需求相冲突时,可以再另外开启注解式事务并设置两种事务的优先级,达到优先使用注解式事务的目的。当order属性的值越大,事务的优先级越高

  • 在applicationContext_trans.xml中增加注解式事务驱动并设置事务优先级
        
        
  • 为applicationContext_trans.xml中的< aop:advisor / >标签设置事务级别,此时如果某业务逻辑层的业务方法使用了注解式事务,则该业务方法的事务遵循注解式事务
 

Spring事务的传播特性

  • 多个事务之间的合并,互斥等都可以通过设置事务的传播特性来解决
  • 常用特性:
  • PROPAGATION_REQUIRED:必被包含事务(增删改必用)
  • PROPAGATION_REQUIRES_NEW:自己开启新事务,不管之前是否有事务
  • PROPAGATION_SUPPORTS:支持事务,如果加入的方法有事务,则遵循该事务,如果没有,不单开事务
  • PROPAGATION_NEVER:不能运行在事务中,如果被包在事务中,抛异常
  • PROPAGATION_NOT_SUPPORTED:不支持事务,运行在非事务环境中
  • 不常用特性:
  • PROPAGATION_MANDATORY:必须包在事务中,没有事务则抛出异常
  • PROPAGATION_NESTED:嵌套事务
  • 注意:
  • 事务必须声明在业务逻辑层
  • 事务传播特性的部分组合结果:下表列出了在User业务实现类中嵌套调用Account业务实现类,当内外层出现不同事务特性组合时,是分别能对users表和accounts表起到数据修改作用还是被事务回滚

Spring事务的隔离原则

  • 未提交读:允许脏读,可能读到其他会话中未提交事务所修改的数据,例如,读取数据后,发生数据回滚,则前面读到的数据就是脏读,读取到了未真实提交的数据
  • 提交读:只能读取到已经提交的数据。oracle等多数数据库默认都是该级别,即读已提交(不重复读)
  • 可重复读:在同一个事务内的查询都是与事务开始时刻一致,是InnoDB数据库引擎的默认级别。在SQL标准中,该隔离级别消除了不可重复读,但是存在幻象读,但InnoDB解决了幻读
  • 串行读:完全串行化的读,每次读都需要获取表级共享锁,读写相互都会阻塞
  • 注意:mysql默认事务处理级别为:可重复读。oracel支持读已提交和串行读两种隔离级别,但是其默认事务隔离级别是:读已提交

添加事务管理器的原因

  • 不同技术对事务提交和回滚的实现简单列举如下,可见不同的技术使用的数据库操作对象不同
    • JDBC:Connection con.commit(); con.rollback();
    • MyBatis:SqlSession sqlSession.commit(); sqlSession.rollback();
    • Hibernate:Session session.commit(); session.rollback();
  • 使用事务管理器,目的就是为了生成相应技术下的数据库连接 + 执行语句的对象
  • 如果使用MyBatis框架,必须使用DataSourceTransactionManager类完成处理
    
    
        
        
    

相关推荐

甲骨文签署多项大型云协议,其一未来可贡献超300亿美元年收入

IT之家7月1日消息,根据甲骨文Oracle当地时间6月30日向美国证券交易委员会(SEC)递交的FORM8-K文件,该企业在始于2025年6月1日的202...

甲骨文获TEMU巨额合同,后者大部分基础设施将迁移至Oracle云

IT之家6月23日消息,Oracle甲骨文创始人、董事长兼首席技术官LarryEllison(拉里埃里森)在本月早些时候的2025财年第四财季和全财年财报电话会议上表示,Oracle...

Spring Boot 自定义数据源设置,这些坑你踩过吗?

你在使用SpringBoot进行后端开发的过程中,是不是也遇到过这样的问题:项目上线后,数据库连接总是不稳定,偶尔还会出现数据读取缓慢的情况,严重影响了用户体验。经过排查,发现很大一部分原因竟然...

一个开箱即用的代码生成器(一个开箱即用的代码生成器是什么)

今天给大家推荐一个好用的代码生成器,名为renren-generator,该项目附带前端页面,可以很方便的选择我们所需要生成代码的表。首先我们通过git工具克隆下来代码(地址见文末),导入idea。...

低代码建模平台-数据挖掘平台(低代码平台的实现方式)

现在来看一下数据连接。·这里是管理数据连接的空间,点击这里可以新增一个数据连接。·输入连接名称,然后输入url,是通过gdbc的方式去连接的数据库,目前是支持mysql、oracle以及国产数据库达梦...

navicat 17.2.7连接oracle数据库提示加载oracle库失败

系统:macOS15.5navicat版本:navicatpremiumlite17.2.7连接oracle测试报错:加载oracle库失败【解决办法】:放达里面找到程序,显示简介里面勾选“使...

开源“Windows”ReactOS更新:支持全屏应用

IT之家6月17日消息,ReactOS团队昨日(6月16日)在X平台发布系列推文,公布了该系统的最新进展,包括升级Explorer组件,支持全屏应用,从Wine项目引入了...

SSL 推出采用全模拟内置混音技术的模拟调音台Oracle

英国调音台传奇品牌SolidStateLogic宣布推出Oracle——一款采用全模拟内置混音技术的调音台,在紧凑的AWS尺寸机箱内集成了大型调音台的功能。该调音台提供24输入和...

47道网络工程师常见面试题,看看有没有你不会的!

你们好,我的网工朋友。网络工程师面试的时候,都会被问到什么?这个问题其实很泛,一般来说,你肯定要先看明白岗位需求写的是什么。基本上都是围绕公司需要的业务去问的。但不可否认的是,那些最基础的概念,多少也...

汉得信息:发布EBS系统安装启用JWS的高效解决方案

e公司讯,从汉得信息获悉,近日,微软官方宣布InternetExplorer桌面应用程序将于2022年6月15日正式停用。目前大部分客户都是使用IE浏览器打开EBS的Form界面,IE停用后,只能使...

36.9K star ! 推荐一个酷炫低代码开发平台!功能太强!

前言最近在逛github,看看能不能搜罗到一些对自己有帮助的开源软件。不经意间看到一个高star的java开源项目:jeecg-boot。进入在线演示版一看,感叹实在是太牛了!此开源项目不管是给来学习...

Linux新手入门系列:Linux下jdk安装配置

本系列文章是把作者刚接触和学习Linux时候的实操记录分享出来,内容主要包括Linux入门的一些理论概念知识、Web程序、mysql数据库的简单安装部署,希望能够帮到一些初学者,少走一些弯路。注意:L...

手把手教你在嵌入式设备中使用SQLite3

摘要:数据库是用来存储和管理数据的专用软件,使得管理数据更加安全,方便和高效。数据库对数据的管理的基本单位是表(table),在嵌入式linux中有时候它也需要用到数据库,听起来好难,其实就是几个函数...

JAVA语言基础(java语言基础知识)

一、计算机的基本概念什么是计算机?计算机(Computer)全称:电子计算机,俗称电脑。是一种能够按照程序运行、自动高速处理海量数据的现代化智能电子设备。由硬件和软件组成、没有安装过任何软件的计算机称...

再见 Navicat!一款开源的 Web 数据库管理工具!

大家好,我是Java陈序员。在日常的开发工作中,常常需要与各种数据库打交道。而为了提高工作效率,常常会使用一些可视化工具进行操作数据库。今天,给大家介绍一款开源的数据库管理工具,无需下载安装软件,基...

取消回复欢迎 发表评论: