欢迎来到皮皮网网首页

【web考试源码下载】【申请职位源码】【亚马逊溯源码】mybatis 事务源码

来源:menice源码运行 时间:2024-11-24 15:44:25

1.《深入理解mybatis原理四》 MyBatis事务管理机制
2.MyBatis事务管理机制
3.常见问题|事务导致Mybatis plus的多数据源失效
4.spring—AOP与事务

mybatis 事务源码

《深入理解mybatis原理四》 MyBatis事务管理机制

       深入理解mybatis原理四:MyBatis事务管理机制

       MyBatis作为Java语言的数据库框架,事务管理是其重要组成部分。本文将详细介绍MyBatis的事务管理实现机制。

       MyBatis的事务管理分为两种形式:JdbcTransaction 和 ManagedTransaction。它们的类图如上所示。

       在MyBatis的web考试源码下载XML配置文件中,我们可以通过节点定义事务配置信息,根据子节点的type属性选择事务管理机制。MyBatis事务的创建则由TransactionFactory事务工厂完成。初始化时,会根据配置生成相应的TransactionFactory实例,进而创建Transaction对象。

       TransactionFactory有两种实现:JdbcTransactionFactory和ManagedTransactionFactory。申请职位源码它们分别用于创建JdbcTransaction和ManagedTransaction。

       TransactionFactory创建Transaction的过程主要包括通过指定的Connection对象创建Transaction或通过DataSource创建Transaction。JdbcTransaction依赖Connection管理事务,而ManagedTransaction则将事务管理权交给了容器。

       JdbcTransaction使用JDBC的提交和回滚机制,与java.sql.Connection的事务处理进行包装。相反,ManagedTransaction不执行任何事务操作,将事务管理权移交给容器。

       若在本地程序中使用MyBatis且配置为"MANAGED",则执行的update操作即使执行了commit,也不会影响数据库,亚马逊溯源码因为事务管理权已交给了容器。因此,在本地非Web程序中,设置为"MANAGED"会导致update操作无效。

       理解MyBatis的事务管理机制,对于开发和优化基于MyBatis的应用至关重要。希望本文能够帮助你深入理解MyBatis事务管理的实现细节。

MyBatis事务管理机制

       MyBatis作为Java数据库框架,其事务管理机制至关重要。本文将深入解析事务分类、配置与实现,揭示MyBatis如何处理事务的saltstack源码调试创建、提交、回滚和关闭过程。

       MyBatis事务管理分为两大类别:一是基于JDBC的手动事务管理,通过java.sql.Connection进行提交(commit)、回滚(rollback)和关闭(close)操作;二是利用程序容器(如JBOSS或Weblogic)的MANAGED事务管理,MyBatis自身并不直接管理事务,而是由容器负责。

       在配置阶段,MyBatis XML文件中会定义数据库连接信息,其中"type"属性决定使用哪种事务管理方式。例如,如果配置为"JDBC",虚拟店铺源码它会通过TransactionFactory创建JdbcTransactionFactory实例;如果是"MANAGED",则创建ManagedTransactionFactory实例。

       解析配置节点时,会根据TransactionFactory类型创建Environment对象,存储在Configuration中。对于JdbcTransaction,它直接使用JDBC的事务管理,通过Connection的commit和rollback操作进行事务控制,而ManagedTransaction则将事务的全程管理权交给容器,自身仅作为容器管理的接口。

常见问题|事务导致Mybatis plus的多数据源失效

       在处理多数据源问题时,使用了Mybatis plus的@DS来切换数据源,但在实际应用中遇到了问题。当使用Oracle和mysql数据库时,发现尽管添加了事务,却导致了多数据源失效。经过排查,得知是事务的传播特性影响了多数据源的切换。为了深入了解,本文将详细探讨事务的传播特性以及如何在多数据源环境下正确应用。

       ### 问题起因

       在多数据库场景下,不同业务逻辑可能会需要访问不同的数据源。使用Mybatis plus的@DS注解可以实现数据源的动态切换。但在实际开发中,遇到的挑战是如何在事务中正确处理多数据源问题。小马在尝试使用Oracle和mysql数据库时发现,尽管事务被正确添加,但数据源切换并未按预期进行,反而导致了问题的产生。这主要与事务的传播特性紧密相关。

       ### 事务的传播特性

       在多事务环境或需要跨数据源操作时,事务的传播特性决定了如何处理多个事务间的交互。Spring框架定义了7种类型的传播行为,每种行为对应不同情况下的事务处理策略。

       ### 注解演示事物传播特性

       为了更直观地理解事务传播特性,以下将通过注解演示不同传播行为的影响。

       #### 传播特性示例

       假设有一个包含三个实现类的案例,分别为`largeTransaction`、`smallTransaction1`和`smallTransaction2`,我们将通过不同的传播特性注解来展示它们对事务行为的影响。

       #### 传播流程

       在具体实现中,`largeTransaction`作为主事务,`smallTransaction1`和`smallTransaction2`作为子事务。下面将通过流程图展示不同传播特性下的事务执行顺序和状态变化。

       1. **REQUIRED**:在当前事务范围内创建一个新事务,如果当前已存在事务,则加入当前事务。所有子事务在当前事务范围内执行,确保原子性和一致性。

        ![REQUIRED传播特性示意图](示意图链接)

       2. **REQUIRES_NEW**:总是开启一个新的事务,忽略当前事务。所有子事务在新的事务范围内执行,确保了独立性和隔离性,但可能导致数据不一致。

        ![REQUIRES_NEW传播特性示意图](示意图链接)

       3. **REQUIRED,REQUIRES_NEW**:在不同的子事务中使用不同传播特性,展现如何灵活配置以适应特定需求。

        ![REQUIRED与REQUIRES_NEW组合示意图](示意图链接)

       ### 结论

       正确理解并应用事务的传播特性对于多数据源场景下的开发至关重要。通过合理选择传播行为,可以有效避免数据一致性问题,并确保业务逻辑的正确执行。希望本文的分析和示例能帮助开发者在实际项目中更好地处理多数据源与事务之间的关系,实现高效、稳定的系统构建。

spring—AOP与事务

        title: spring——AOP与事务.md

        date: -- ::

        categories: [Spring]

        tags: [AOP,事务]

        toc: true

        先列出源码中比较重点的几个类:

        1、<aop:before method="before" pointcut-ref="myMethods"/>包装成一个advisor

        2、AspectJAwareAdvisorAutoProxyCreator,当实例化所有bean都会执行到AspectJAwareAdvisorAutoProxyCreatorç±»

        它会检测bean是否advisor以及advice存在,如果有就说明这个bean有切面,有切面那么就会生成代理

        3、jdk的代理,bean里面的所有advisor加入到proxyFactory。

        4、jdkDynamicProxy invoke,拿到bean里面的所有Interceptor,会循环proxyFactory里面的所有advisor

        里面有advice,里面的advice有两种类型,要么是advice,要么是MethodInterceptor类型的

        5、当代理对象调用方式,是一个MethodInterceptor类型的类的链式调用过程,直到容器的大小和索引一致的时候调用JoinPoint目标方法

        before:this.advice.before(),invocation.processd();

        装配参数,切面里面before方法的method对象,method.getParamterTypes()[0]

        最终会把advice封装成MethodInterceptor类型的对象

        程序执行的某个特定位置:如类开始初始化前、类初始化后、类某个方法调用前、调用后、方法抛出异常后。一个类或一段程序代码拥有一些具有边界性质的特定点,这些点中的特定点就称为“连接点”。Spring仅支持方法的连接点,即仅能在方法调用前、方法调用后、方法抛出异常时以及方法调用前后这些程序执行点织入增强。连接点由两个信息确定:第一是用方法表示的程序执行点;第二是用相对点表示的方位。

        每个程序类都拥有多个连接点,如一个拥有两个方法的类,这两个方法都是连接点,即连接点是程序类中客观存在的事物。AOP通过“切点”定位特定的连接点。连接点相当于数据库中的记录,而切点相当于查询条件。切点和连接点不是一对一的关系,一个切点可以匹配多个连接点。在Spring中,切点通过org.springframework.aop.Pointcut接口进行描述,它使用类和方法作为连接点的查询条件,Spring AOP的规则解析引擎负责切点所设定的查询条件,找到对应的连接点。其实确切地说,不能称之为查询连接点,因为连接点是方法执行前、执行后等包括方位信息的具体程序执行点,而切点只定位到某个方法上,所以如果希望定位到具体连接点上,还需要提供方位信息。

        增强是织入到目标类连接点上的一段程序代码,在Spring中,增强除用于描述一段程序代码外,还拥有另一个和连接点相关的信息,这便是执行点的方位。结合执行点方位信息和切点信息,我们就可以找到特定的连接点。

        增强逻辑的织入目标类。如果没有AOP,目标业务类需要自己实现所有逻辑,而在AOP的帮助下,目标业务类只实现那些非横切逻辑的程序逻辑,而性能监视和事务管理等这些横切逻辑则可以使用AOP动态织入到特定的连接点上。

        引介是一种特殊的增强,它为类添加一些属性和方法。这样,即使一个业务类原本没有实现某个接口,通过AOP的引介功能,我们可以动态地为该业务类添加接口的实现逻辑,让业务类成为这个接口的实现类。

        织入是将增强添加对目标类具体连接点上的过程。AOP像一台织布机,将目标类、增强或引介通过AOP这台织布机天衣无缝地编织到一起。根据不同的实现技术,AOP有三种织入的方式:

        a、编译期织入,这要求使用特殊的Java编译器。

        b、类装载期织入,这要求使用特殊的类装载器。

        c、动态代理织入,在运行期为目标类添加增强生成子类的方式。

        Spring采用动态代理织入,而AspectJ采用编译期织入和类装载期织入。

        一个类被AOP织入增强后,就产出了一个结果类,它是融合了原类和增强逻辑的代理类。根据不同的代理方式,代理类既可能是和原类具有相同接口的类,也可能就是原类的子类,所以我们可以采用调用原类相同的方式调用代理类。

        切面由切点和增强(引介)组成,它既包括了横切逻辑的定义,也包括了连接点的定义,Spring AOP就是负责实施切面的框架,它将切面所定义的横切逻辑织入到切面所指定的连接点中。

        advisor: pointCut advice

        一类功能的增强

        around方法里面代码切面

        事务切面

        缓存切面

        日志切面

        事务(Transaction),一般是指要做的或所做的事情。在计算机术语中是指访问并可能更新数据库中各种数据项的一个程序执行单元(unit)。是数据库操作的最小工作单元,是作为单个逻辑工作单元执行的一系列操作;这些操作作为一个整体一起向系统提交,要么都执行、要么都不执行;事务是一组不可再分割的操作集合(工作逻辑单元)。

        大致流程形如

        数据库事务拥有几大特性:

        事务的四大特性:

        事务是数据库的逻辑工作单位,事务中包含的各操作要么都做,要么都不做

        事 务执行的结果必须是使数据库从一个一致性状态变到另一个一致性状态。因此当数据库只包含成功事务提交的结果时,就说数据库处于一致性状态。如果数据库系统 运行中发生故障,有些事务尚未完成就被迫中断,这些未完成事务对数据库所做的修改有一部分已写入物理数据库,这时数据库就处于一种不正确的状态,或者说是 不一致的状态。

        一个事务的执行不能其它事务干扰。即一个事务内部的操作及使用的数据对其它并发事务是隔离的,并发执行的各个事务之间不能互相干扰。

        也称永久性,指一个事务一旦提交,它对数据库中的数据的改变就应该是永久性的。接下来的其它操作或故障不应该对其执行结果有任何影响。

        个人理解,事务在Spring中是借助AOP技术来实现的,可以作为AOP中的一个事务切面。spring源码对事务的处理逻辑,自己研究吧!

        ORM框架中以Mybatis为例,事务处理就是用到了一个类Transaction,部分源码如下

        可以看出Transaction管理的就是一个connection,而connection我们很清楚是与用户会话挂钩的。

        那么关系就是Transaction 管理Connection ,而connection与 用户session一对一存在。

        在springBoot中,只需要加入POM就可以了,配合注解使用即可。

        接下来就是事务的控制了。

        首先事务有几大传播属性:

        其中最常见的,用得最多就 PROPAGATION_REQUIRED、PROPAGATION_REQUIRES_NEW、 PROPAGATION_NESTED 这三种。事务的传播属性是 spring 特有的,是 spring 用来控制方法事务的一种手段,说直白点就是用来控制方法是否使用同一事务的一种属性,以及按照什么规则回滚的一种手段。

        下面用代码演示这三种属性的机制:

        事务的默认属性就是required,通过Transactional.java中的Propagation propagation() default Propagation.REQUIRED; 可以看出。

        这种情况就是事务1,事务2 都加入到了事务0中。不管是1,2哪个事务抛出异常,事务0都会回滚。数据添加会失败。

        这种情况就是:

        事务0(required) {

        ​ 事务1 (REQUIRES_NEW)

        ​ 事务2

        }

        此时。

        情况a:

        1、如果只是事务2出现了异常,那么事务1会提交,事务2加入到事务0中会回滚。

        2、如果只是事务1出现了异常,那么事务1会回滚,向上层事务0抛异常,事务2会加入到事务0中,这时都会回滚。

        情况b:

        如果事务1,事务2都是REQUIRES_NEW传播属性。那么结果就是:

        1、如果事务1,抛出了异常,那么事务2是不会执行的,那么事务0必然回滚。

        2、如果事务2,抛出异常,那么事务1会提交,表中会有数据。事务2有异常回滚并抛出,事务0回滚。

        NESTED属性其实就是创建了回滚点,有异常时,会回滚到指定的回滚点。

        在这通过代码测试,出现一种情况是,无论事务1,事务2哪个有异常,数据都不会插入成功,原因是,不论是事务1还是事务2都会向事务0抛出异常,事务0捕获到异常后,执行rollback()方法,这就操作成了,事务的全部回滚。

        如果想要事务1和事务2 想要根据自己的回滚点回滚,那么事务0必须自己处理异常,不让spring捕获到这个异常,那么就满足了。把代码改成这种:

        Jack大佬提供了,伪代码分析法。

        按照Spring源码的事务处理逻辑,伪代码大致为: