spring 事务 mysql 锁_Spring事务管理实现原理及MySQL InnoBD引擎行锁概述

本文深入探讨了Spring的事务管理机制,包括基于AOP的动态代理实现,如JDK和CGLIB代理的区别,以及@Transactional注解的使用注意事项。此外,还介绍了Spring事务的两种管理方式——动态代理和静态编织。同时,文章详细阐述了MySQL InnoDB存储引擎的行锁类型,如排它锁和共享锁,并讨论了不同事务隔离级别下的行锁行为和一致性非锁定读的概念。
摘要由CSDN通过智能技术生成

Spring实现事务管理的机制

Spring事务管理是基于AOP编程思想实现,Spring框架被广泛使用的原因之一,就是提供了强大的事务管理机制。

AOP是什么?我们常说的AOP并不是指一种开发技术,而是一种编程思想,AOP的核心概念就是面向切面编程,实现可插拔,降低程序之前的耦合性,提高重用性。

Spring AOP 基于动态代理实现,一种是JDK动态代理,另一种是CGLIB动态代理。

spring2.5之前声明式事务可以这样实现:

pointcut="execution(* com.junlong.demo.service.DemoService.*(..))"/>

在spring2.5之后声明式事务,增加了事务注解驱动,这样可以更灵活的控制在哪声明事务,并且Spring2.5之后的一个核心主题就是全面的支持注解方式

几个核心的注意事项

一、Spring事务管理基于动态代理的两种方式(JDKProxy、CGLIBProxy)

1.如果代理对象实现了接口则采用JDK动态代理实现,JDK动态代理基于接口进行代理的,它是通过在运行时创建一个接口的实现类来完成对目标对象的代理,所以使用@Transactional 注解的类想要基于JDK动态代理进行事务控制必须实现一个接口。

Spring默认会在JDK动态代理和CGLIB动态代理之间进行切换,如果被代理的类实现了接口则会使用JDK动态代理,否则会使用CGLIB动态代理。

如果想强制使用基于类的代理,可以设置proxy-target-class=true,这样Spring会使用CGLIB代理,在使用CGLIB代理时@Transactional必须写在具体的实现类上或者实现方法上,因为CGLIB动态代理是在运行时对代理对象进行继承扩展子类,所以声明final的类是无法使用CGLIB代理的。

Are class-based (CGLIB) proxies to be created? By default, standard

Java interface-based proxies are created.

Note: Class-based proxies require the @Transactional annotation to be

defined on the concrete class. Annotations in interfaces will not work

in that case (they will rather only work with interface-based proxies)!

]]>

2.官方文档介绍@Transactional 注解只有在public的方法上生效,这是因为Spring事务注解驱动是基于Spring AOP(也就是默认的方式是基于动态代理实现)实现的。

3.同一个java类内部方法调用本类内部的其他方法并不会引起事务行为,即使被调用方法使用@Transactional注解进行修饰,这也是因为Spring实现事务代理是默认是基于Spring AOP(也就是默认的方式是基于动态代理实现)实现的。

二、Spring事务管理实现的两种方式(动态代理、静态编织)

Should annotated beans be proxied using Spring's AOP framework,

or should they rather be weaved with an AspectJ transaction aspect?

AspectJ weaving requires spring-aspects.jar on the classpath,

as well as load-time weaving (or compile-time weaving) enabled.

Note: The weaving-based aspect requires the @Transactional annotation to be

defined on the concrete class. Annotations in interfaces will not work

in that case (they will rather only work with interface-based proxies)!

]]>

mode模式默认采用代理模式(mode="proxy"),在proxy模式中采用AOP的动态代理来进行事务管理,是在运行期间基于JDK动态代理或者GCLIB动态代理来实现,在代理模式中(mode="proxy")只有A类中方法调用另外一个B类声明@Transactional的方法才会被代理截获进行事务控制,在A类本类中调用本类的其他带有@Transactional的方法不会经过动态代理。

然而mode="aspectj"则采用静态编织的方式(aspectj是一种编译技术)其需要spring-aspects.jar,是在编译期间或者载入期间对代理对象进行修改字节码织入事务实现,所以不管你的方法的可见度(public、private)是什么都可以实现事务管理,这跟proxy动态代理是完全不同的。

,其实是

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值