MyBatis事务管理

article/2025/9/16 4:00:57

一、概述

事务管理对于企业应用来说是至关重要的,即使出现异常情况,它也可以保证数据的一致性。
Spring Framework对事务管理提供了一致的抽象,其特点如下:

为不同的事务API提供一致的编程模型,比如JTA(Java Transaction API), JDBC, Hibernate, JPA(Java Persistence API和JDO(Java Data Objects)支持声明式事管理,特别是基于注解的声明式事务管理,简单易用提供比其他事务API如JTA更单的编程式事务管理API与spring数据访问抽象的完美集成。

二、事务管理方式

spring支持编程式事务管理和声明式事务管理两种方式。

编程式事务管理使用TransactionTemplate或者直接使用底层的PlatformTransactionManager。对于编程式事务管理,spring推荐使用TransactionTemplate

声明式事务管理建立在AOP之上的。其本质是对方法前后进行拦截,然后在目标方法开始之前创建或者加入一个事务,在执行完目标方法之后根据执行情况提交或者回滚事务。声明式事务最大的优点就是不需要通过编程的方式管理事务,这样就不需要在业务逻辑代码中掺杂事务管理的代码,只需在配置文件中做相关的事务规则声明(或通过基于@Transactional注解的方式),便可以将事务规则应用到业务逻辑中。

显然声明式事务管理要优于编程式事务管理,这正是spring倡导的非侵入式的开发方式。声明式事务管理使业务代码不受污染,一个普通的POJO对象,只要加上注解就可以获得完全的事务支持。和编程式事务相比,声明式事务唯一不足地方是,后者的最细粒度只能作用到方法级别,无法做到像编程式事务那样可以作用到代码块级别。但是即便有这样的需求,也存在很多变通的方法,比如,可以将需要进行事务管理的代码块独立为方法等等。

声明式事务管理也有两种常用的方式,一种是基于tx和aop名字空间的xml配置文件,另一种就是基于@Transactional注解。显然基于注解的方式更简单易用,更清爽。

三、spring事务特性

spring所有的事务管理策略类都继承自org.springframework.transaction.PlatformTransactionManager接口

public interface PlatformTransactionManager {TransactionStatus getTransaction(TransactionDefinition definition)throws TransactionException;void commit(TransactionStatus status) throws TransactionException;void rollback(TransactionStatus status) throws TransactionException;
}

除了指定不同的事务管理器之后,还能对事务进行隔离级别和传播行为的控制,下面分别详细解释:



四、隔离级别

隔离级别是指若干个并发的事务之间的隔离程度,与我们开发时候主要相关的场景包括:脏读取、重复读、幻读。
对于脏读、不可重复读和幻读详见:何为脏读、不可重复读、幻读

我们可以看org.springframework.transaction.annotation.Isolation枚举类中定义了五个表示隔离级别的值:

public enum Isolation {DEFAULT(-1),READ_UNCOMMITTED(1),READ_COMMITTED(2),REPEATABLE_READ(4),SERIALIZABLE(8);
}
  • DEFAULT:这是默认值,表示使用底层数据库的默认隔离级别。对大部分数据库而言,通常这值就是:READ_COMMITTED。
  • READ_UNCOMMITTED:该隔离级别表示一个事务可以读取另一个事务修改但还没有提交的数据。该级别不能防止脏读和不可重复读,因此很少使用该隔离级别。
  • READ_COMMITTED:该隔离级别表示一个事务只能读取另一个事务已经提交的数据。该级别可以防止脏读,这也是大多数情况下的推荐值。
  • REPEATABLE_READ:该隔离级别表示一个事务在整个过程中可以多次重复执行某个查询,并且每次返回的记录都相同。即使在多次查询之间有新增的数据满足该查询,这些新增的记录也会被忽略。该级别可以防止脏读和不可重复读。
  • SERIALIZABLE:所有的事务依次逐个执行,这样事务之间就完全不可能产生干扰,也就是说,该级别可以防止脏读、不可重复读以及幻读。但是这将严重影响程序的性能。通常情况下也不会用到该级别。

指定方法:通过使用isolation属性设置,例如:

@Transactional(isolation = Isolation.DEFAULT)

五、传播行为

所谓事务的传播行为是指,如果在开始当前事务之前,一个事务上下文已经存在,此时有若干选项可以指定一个事务性方法的执行行为。

我们可以看org.springframework.transaction.annotation.Propagation枚举类中定义了6个表示传播行为的枚举值:

public enum Propagation {REQUIRED(0),SUPPORTS(1),MANDATORY(2),REQUIRES_NEW(3),NOT_SUPPORTED(4),NEVER(5),NESTED(6);
}
  • REQUIRED:如果当前存在事务,则加入该事务;如果当前没有事务,则创建一个新的事务。
  • SUPPORTS:如果当前存在事务,则加入该事务;如果当前没有事务,则以非事务的方式继续运行。
  • MANDATORY:如果当前存在事务,则加入该事务;如果当前没有事务,则抛出异常。
  • REQUIRES_NEW:创建一个新的事务,如果当前存在事务,则把当前事务挂起。
  • NOT_SUPPORTED:以非事务方式运行,如果当前存在事务,则把当前事务挂起。
  • NEVER:以非事务方式运行,如果当前存在事务,则抛出异常。
  • NESTED:如果当前存在事务,则创建一个事务作为当前事务的嵌套事务来运行;如果当前没有事务,则该取值等价于REQUIRED。

指定方法:通过使用propagation属性设置,例如:

@Transactional(propagation = Propagation.REQUIRED)

六、事务超时

所谓事务超时,就是指一个事务所允许执行的最长时间,如果超过该时间限制但事务还没有完成,则自动回滚事务。在 TransactionDefinition 中以 int 的值来表示超时时间,其单位是秒。

默认设置为底层事务系统的超时值,如果底层数据库事务系统没有设置超时值,那么就是none,没有超时限制。



七、事务只读属性

只读事务用于客户代码只读但不修改数据的情形,只读事务用于特定情景下的优化,比如使用Hibernate的时候。
默认为读写事务。



八、spring事务回滚规则

指示spring事务管理器回滚一个事务的推荐方法是在当前事务的上下文内抛出异常。spring事务管理器会捕捉任何未处理的异常,然后依据规则决定是否回滚抛出异常的事务。

默认配置下,spring只有在抛出的异常为运行时unchecked异常时才回滚该事务,也就是抛出的异常为RuntimeException的子类(Errors也会导致事务回滚),而抛出checked异常则不会导致事务回滚。
可以明确的配置在抛出那些异常时回滚事务,包括checked异常。也可以明确定义那些异常抛出时不回滚事务。

还可以编程性的通过setRollbackOnly()方法来指示一个事务必须回滚,在调用完setRollbackOnly()后你所能执行的唯一操作就是回滚。



九、@Transactional注解

用法

@Transactional 可以作用于接口、接口方法、类以及类方法上。当作用于类上时,该类的所有 public 方法将都具有该类型的事务属性,同时,我们也可以在方法级别使用该标注来覆盖类级别的定义。

虽然 @Transactional 注解可以作用于接口、接口方法、类以及类方法上,但是 Spring 建议不要在接口或者接口方法上使用该注解,因为这只有在使用基于接口的代理时它才会生效。另外, @Transactional 注解应该只被应用到 public 方法上,这是由 Spring AOP 的本质决定的。如果你在 protected、private 或者默认可见性的方法上使用 @Transactional 注解,这将被忽略,也不会抛出任何异常。

默认情况下,只有来自外部的方法调用才会被AOP代理捕获,也就是,类内部方法调用本类内部的其他方法并不会引起事务行为,即使被调用方法使@Transactional注解进行修饰。

在使用@Transactional注解前,请在启动类上加上注解@EnableTransactionManagement来开启事务。

@EnableTransactionManagement  //开启事务
public class AdminApplication {public static void main(String[] args) {SpringApplication.run(AdminApplication.class, args);}}

注:
java动态代理是利用反射机制生成一个实现代理接口的匿名类,在调用具体方法前调用InvokeHandler来处理。

而cglib动态代理是利用asm开源包,对代理对象类的class文件加载进来,通过修改其字节码生成子类来处理。

1、如果目标对象实现了接口,默认情况下会采用JDK的动态代理实现AOP
2、如果目标对象实现了接口,可以强制使用CGLIB实现AOP
3、如果目标对象没有实现了接口,必须采用CGLIB库,spring会自动在JDK动态代理和CGLIB之间转换


http://chatgpt.dhexx.cn/article/iMc0Ca5R.shtml

相关文章

深入浅出Mybatis系列(五)Mybatis事务篇

在学习Mysql事务开始,分为两步。一.先看下Mysql的事务级别都有什么,然后看Mysql的事务级别设置命令。及常见问题。二.JDK是如何处理数据库操作的呢? Mybatis是如何实现JDK定义的事务级别操作。 一.Mysql的事务级别及常见概念 MySQL事务隔离级别 事务隔离级别脏读不可重复读幻…

详解 MyBatis 事务管理,彻底颠覆你对事务的理解!

来源:https://my.oschina.net/zudajun/blog/666764 前言 说到数据库事务,人们脑海里自然不自然的就会浮现出事务的四大特性、四大隔离级别、七大传播特性。四大还好说,问题是七大传播特性是哪儿来的?是 Spring 在当前线程内&…

MyBatis的事务

Mybatis管理事务是分为两种方式: (1)使用JDBC的事务管理机制,就是利用java.sql.Connection对象完成对事务的提交 (2)使用MANAGED的事务管理机制,这种机制mybatis自身不会去实现事务管理,而是让程序的容器(JBOSS,WebLogic)来实现对…

MyBatis--事务

事务是基于关系型数据库的企业应用的重要组成部分,用来确保应用程序数据的完整性和一致性。 事务就是一个系列(一组、几个)操作的集合单元,这些操作要么全部完成,要么全部失败,如果某一个操作失败,就算是已经成功执行…

ResNet网络结构解析

ResNet是识别、检测中常用的backbone,看检测相关论文的时候重点都在方法创新上,并没有特别在意网络结构,但是到自己跑实验改网络的时候就涉及到结构细节问题,于是详细的看了下ResNet网络结构。下图是ResNet的网络结构简图&#xf…

resnet网络结构图

很重要,单独放

ResNet网络结构,BN以及迁移学习详解

网络中的亮点: 1.超深的网络结构(超过1000层) 2.提出residual(残差)模块 3.使用Batch Normalization加速训练(丢弃dropout) 左边是将卷积层和池化层进行一个简单的堆叠所搭建的网络结构 20层的训练错误率大概在1%…

ResNet网络结构详解(Tensorflow2.6.0实现网络结构)

文章目录 1.ResNetX网络结构表(1)论文地址:(2)ResNet18网络结构:(3)ResNet34网络结构: 2.卷积神经网络的发展(1).卷积神经网络的发展:(2&#xff…

ResNet网络结构详解,网络搭建,迁移学习

前言: 参考内容来自up:6.1 ResNet网络结构,BN以及迁移学习详解_哔哩哔哩_bilibili up的代码和ppt:https://github.com/WZMIAOMIAO/deep-learning-for-image-processing 一、简介 ResNet 网络是在 2015年 由微软实验室提出&#xf…

ResNet网络结构详解与模型的搭建

ResNET(Deep Residual Learning for Image Recognition ) ResNet网络是在2015年由微软实验室提出,斩获当年ImageNet竞赛中分类任务第一名,目标检测第一名。获得COCO数据集中目标检测第一名,图像分割第一名。下图是ResNet34层模型的结构简图。…

Resnet网络结构图和对应参数表的简单理解

Resnet Resnet即就是残差网络,本文主要是对于resnet给出的网络结构图进行简单解释。 网络结构图 以上就是34层网络的网络结构图。 以上是18层、34层、50层、101层以及152层网络所对应的残差块。 我刚开始在网上看到这两张图片的时候,感觉一点都不懂&a…

pytorch Resnet 网络结构

最近在学习廖老师的pytorch教程,学到Resnet 这部分着实的烧脑,这个模型都捣鼓了好长时间才弄懂,附上我学习过程中最为不解的网络的具体结构连接(网上一直没有找到对应网络结构,对与一个自学的学渣般的我,很…

ResNet网络结构解析--Pytorch

ResNet101–DSSD/SSD (1)ResNet在Pytorch官方代码中有5种不同深度的结构,分别为18、34、50、101、152(各网络深度指的是“需要通过训练更新参数“的层数,如卷积层,全连接层等),和论…

ResNet网络结构详解及代码复现

1. ResNet论文详解 1.1. Introduction 一般网络越深&#xff0c;特征就越丰富&#xff0c;模型效果也就越好。在深度重要的驱动下&#xff0c;出现了2个问题&#xff1a; 梯度消失和梯度爆炸&#xff1a; 梯度消失&#xff1a;误差梯度<1&#xff0c;当网络层数增多时&…

resnet50网络结构_pytorch实践(改造属于自己的resnet网络结构并训练二分类网络)

我的CSDN博客:https://blog.csdn.net/litt1e 我的公众号:工科宅生活 在学习pytorch过程中,突然想拥有属于自己的网络结构,于是便自己选择了一个比较简单的resnet18进行改造,并用其对蚂蚁和蜜蜂进行分类,比较一下没有经过预训练的resnet18好还是自己改造的resnet_diy好。 …

【DL系列】ResNet网络结构详解、完整代码实现

Name&#xff1a; Deep Residual Learning for Image Recognition Author&#xff1a; 何恺明团队 Publiced&#xff1a; 2015.12_CVPR 文章目录 前言1. 残差网络待解决的问题2. ResNet模型亮点 ResNet模型结构1. 残差学习2. Residual模块3. ResNet模型 ResNet-layers模型完整代…

pytorch实现resnet网络结构

ResNet结构和pytorch实现 resnet的网络结构都是经过5个不同数量的残差块最后一个全连接分类完成的。 在resnet50以后&#xff0c;由于层数的增加残差块发生了变化&#xff0c;从原来3x3卷积变为三层卷积&#xff0c;卷积核分别为1x1、3x3、1x1&#xff0c;减少了网络参数。主…

ResNet网络结构搭建

ResNet 下图为包含有18层(17个卷积层和1个全连接层)、34层(33个卷积层和1个全连接层)、50层(49个卷积层和1个全连接层)、101层(100个卷积层和1个全连接层)、152层(151个卷积层和1个全连接层)的resnet结构 下图是论文中给出的两种残差结构。左边的残差结构是针对层数较少网络&a…

ResNet网络结构

注&#xff1a;深度好像就是channel w*h*c 根据b站up霹雳吧啦的讲解做的笔记 视频地址6.1 ResNet网络结构&#xff0c;BN以及迁移学习详解_哔哩哔哩_bilibiliR 6.2 使用pytorch搭建ResNet并基于迁移学习训练_哔哩哔哩_bilibili ResNet网络解决梯度消失、爆炸&#xff0c;以及…

经典网络ResNet介绍

经典网络ResNet(Residual Networks)由Kaiming He等人于2015年提出&#xff0c;论文名为《Deep Residual Learning for Image Recognition》&#xff0c;论文见&#xff1a;https://arxiv.org/pdf/1512.03385.pdf ResNet要解决的是深度神经网络的”退化(degradation)”问题&…