Loading

Spring(1)

 

1.什么是Spring?

Spring是一个轻量级Java开发框架。

      基于POJO的轻量级和最小侵入性编程;

      通过依赖注入和面向接口实现松耦合;

      基于切面和惯例进行声明式编程;

      通过切面和模板减少样板式代码

Spring框架的核心:IOC容器和AOP模块。通过IOC容器管理POJO对象以及它们之间的耦合关系;通过AOP以动态非侵入的方式增强服务。

2.Spring的优缺点?

1.方便解耦,简化开发

2.AOP编程的支持

3.声明式事务的支持

4.方便程序的测试

5.方便集成各种优秀的框架

 

Spring里用到了哪些设计模式?

单例模式:Spring中的Bean默认情况下都是单例的

工厂模式:工厂模式是通过BeanFactory和ApplicationContext来生产Bean对象

代理模式:Spring的AOP功能用到了JCK动态代理和CGLIB代理

模板方法模式:主要是一些对数据库操作的类用到,因为查询数据库的建立连接,执行查询,关闭连接几个过程,非常适用模板方法。

 

IOC怎么理解?

     IOC叫做控制反转(Inversion of Control),指的就是通过Spring来管理对象的创建,配置和生命周期,这样相当于把控制权交给了Spring,不需要人工来管理对象之间复杂的依赖关系,这样做可以解耦。在Spring里面,主要提供了BeanFactory和ApplicationContext两种IOC容器,通过他们来实现对Bean的管理。

BeanFactory和ApplicationContext有什么区别?

BeanFactory和ApplicationContext都是Spring的两大核心接口,都可以当作Spring的容器。ApplicationContext是BeanFactory的子接口。

加载方式:

       BeanFactory采用的是延迟加载形式来注入Bean的,只有在使用到某个Bean时(调用getBean()),才对Bean进行加载实例化。

       ApplicationContext,它是在容器启动时,一次性创建了所有的Bean,ApplicationContext启动后预载入所有的单实例Bean,确保你需要的时候,你就不用等待,因为已经创建好了。相较于基本的BeanFactory,占用内存空间,程序启动较慢。

依赖关系:

       BeanFactory:是Spring里面最底层的接口,包含了Bean的定义,读取Bean配置文档,管理bean的加载,实例化,控制bean的生命周期,维护bean之间的依赖关系。

       ApplicationContext接口作为BeanFactory的派生,还提供了更完整的框架功能:

                 * 继承MessageSource,支持国际化

                 * 同时加载多个配置文件

                 * 统一的资源文件访问方式

 创建方式:

       BeanFactory:通常以编程的方式被创建,ApplicationContext还能以声明的方式创建,如ContextLoader

注册方式:

       BeanFactory需要手动注册,而ApplicationContext则是自动注册

 

Spring是如何设计容器的,BeanFactory和ApplicationContext的关系详解

Ioc在Spring里,只需要低级容器就可以实现:

         加载配置文件,解析成BeanDefinition放在Map里;

         调用getBean的时候,从BeanDefinition所属的Map里,拿出Class对象进行实例化,同时有依赖关系,将递归调用getBean方法--完成依赖注入

至于高级容器 ApplicationContext,他包含了低级容器的功能,当他执行 refresh 模板方法的时候,将刷新整个容器的 Bean。

ApplicationContext通常的实现是什么?FileSystemXmlApplicationContext:此容器从一个XML文件中加载beans的定义,XML Bean 配置文件的全路径名必须提供给它的构造函数。

ClassPathXmlApplicationContext:此容器也从一个XML文件中加载beans的定义,这里,你需要正确设置classpath因为这个容器将在classpath里找bean配置。

WebXmlApplicationContext:此容器加载一个XML文件,此文件定义了一个WEB应用的所有bean。

什么是Spring的依赖注入?

相较于IoC而言,依赖注入(DI)更加准确的描述了IOC的设计理念,也就是由容器动态的将某种依赖关系的目标对象实例注入到应用系统中的各个关联的组件之中

依赖注入有什么优势?

让容器全权负责依赖查询,受管组件只需要暴露JavaBean的setter方法胡总和带参数的构造器或者接口,使容器可以在初始化时组装对象的依赖关系。  

有哪些不同类型的依赖注入实现方式?

接口注入,Setter方法注入和构造器注入 三种方式,接口注入从Spring4开始已经被废弃

构造器依赖注入:通过容器触发一个类的构造器来实现的,该类有一系列参数,每个参数代表一个对其他类的依赖

Setter方法注入:Setter方法注入是容器通过调用无参构造器或无参static工厂方法实例化bean之后,调用bean的setter方法,即实现了基于setter的依赖注入。

构造器依赖注入和Setter方法注入的区别?构造函数注入:不会覆盖setter属性,任意修改都会创建一个新实例,没有部分注入

Setter方法注入:会覆盖setter属性,任意修改不会创建一个新实例,有部分注入

如何给Spring容器提供配置元数据?Spring有几种配置方式?

XML配置文件

基于注解的配置

基于Java的配置

你怎样定义类的作用域?

可以通过bean定义中的scope属性来定义,当Spring要在需要的时候每次生产一个新的bean实例,bean的scope属性被指定为prototype,当一个bean每次使用的时候必须返回同一个实例,这个bean的scope属性必须为singleton。

解释Spring支持的集中bean的作用域

singleton:bean在每个Spring ioc容器中只有一个实例

prototype:一个bean的定义可以有多个实例

request:每次http请求都会创建一个bean,该作用域仅在基于web的Spring ApplicationContext情形下有效。
session:在一个HTTP Session中,一个bean定义对应一个实例。该作用域仅在基于web的Spring ApplicationContext情形下有效。
global-session:在一个全局的HTTP Session中,一个bean定义对应一个实例。该作用域仅在基于web的Spring ApplicationContext情形下有效。

Spring框架中的单例bean是线程安全的吗?

不是,Spring框架中的单例bean不是线程安全的。

实际上大部分时候 spring bean 无状态的(比如 dao 类),所有某种程度上来说 bean 也是安全的,但如果 bean 有状态的话(比如 view model 对象),那就要开发者自己去保证线程安全了,最简单的就是改变 bean 的作用域,把“singleton”变更为“prototype”,这样请求 bean 相当于 new Bean()了,所以就可以保证线程安全了。

有状态就是有数据存储功能。
无状态就是不会保存数据。

Spring如何处理线程并发问题?Spring对一些Bean中非线程安全状态采用ThreadLocal进行处理,解决线程安全问题。

ThreadLocal和线程同步机制都是为了解决多线程中相同变量的访问冲突问题。同步机制采用了“时间换空间”的方式,仅提供一份变量,不同的线程在访问前需要获取锁,没获得锁的线程则需要排队。而ThreadLocal采用了“空间换时间”的方式。

ThreadLocal会为每一个线程提供一个独立的变量副本,从而隔离了多个线程对数据的访问冲突。因为每一个线程都拥有自己的变量副本,从而也就没有必要对该变量进行同步了。ThreadLocal提供了线程安全的共享对象,在编写多线程代码时,可以把不安全的变量封装进ThreadLocal。

解释Spring框架中bean的生命周期

在传统的java应用中,使用Java关键字new进行bean实例化,然后该bean就可以使用了。一旦该bean不再被使用,则由Java自动进行垃圾回收。

Spring对bean进行实例化;

Spring将值和bean的引用注入到bean对应的属性中;

如果bean实现了BeanNameAware接口,Spring将bean的ID传递给setBean-Name()方法;

如果bean实现了BeanFactoryAware接口,Spring将调用setBeanFactory()方法,将BeanFactory容器实例传入;

如果bean实现了ApplicationContextAware接口,Spring将调用setApplicationContext()方法,将bean所在的应用上下文的引用传入进来;

如果bean实现了BeanPostProcessor接口,Spring将调用它们的post-ProcessBeforeInitialization()方法;

如果bean实现了InitializingBean接口,Spring将调用它们的after-PropertiesSet()方法。类似地,如果bean使用initmethod声明了初始化方法,该方法也会被调用;

如果bean实现了BeanPostProcessor接口,Spring将调用它们的post-ProcessAfterInitialization()方法;

此时,bean已经准备就绪,可以被应用程序使用了,它们将一直驻留在应用上下文中,直到该应用上下文被销毁;

如果bean实现了DisposableBean接口,Spring将调用它的destroy()接口方法。同样,如果bean使用destroy-method声明了销毁方法,该方法也会被调用。

哪些是重要的bean生命周期方法?你能重载它们吗?

setup:它是在容器加载bean的时候被调用

teardown:实在容器卸载类的时候被调用

bean 标签有两个重要的属性(init-method和destroy-method)。用它们你可以自己定制初始化和注销方法。它们也有相应的注解(@PostConstruct和@PreDestroy)

什么是Spring的内部bean?什么是Spring inner beans?

在Spring框架中,当一个bean仅被用作另一个bean的属性时,它能被声明为一个内部bean。内部bean可以用setter注入“属性”和构造方法注入“构造参数”的方式来实现,内部bean通常是匿名的,它们的Scope一般是prototype。

在Spring中如何注入一个Java集合?

<list>类型用于注入一列值,允许有相同的值。
<set>类型用于注入一组值,不允许有相同的值。
<map>类型用于注入一组键值对,键和值都可以为任意类型。
<props>类型用于注入一组键值对,键和值都只能为 String 类型。

<!-- 给list注入值 可以有相同的多个对象  -->
22        <property name="empList">
23            <list>
24                <ref bean="emp1" />
25                <ref bean="emp2"/>
26            </list>
27        </property>
28        <!-- 给set注入值 不能有相同的对象 -->
29        <property name="empSets">
30            <set>
31                <ref bean="emp1" />
32                <ref bean="emp2"/>
33            </set>
34        </property>
35        
36        <!-- 给map注入值 只要map中的key值不一样就可以装配value -->
37        <property name="empMap">
38            <map>
39                <entry key="1" value-ref="emp1" />
40                <entry key="2" value-ref="emp2" />
41            </map>
42        </property>
43        
44        <!-- 给属性集合配置 -->
45        <property name="pp">
46            <props>
47                <prop key="pp1">hello</prop>
48                <prop key="pp2">world</prop>
49            </props>
50        </property>
51    </bean>
52    <bean id="emp1" class="com.LHB.collection.Employee">
53        <property name="name">
54            <value>北京</value>
55        </property>
56    </bean>
57     <bean id="emp2" class="com.LHB.collection.Employee">
58        <property name="name">
59            <value>天津</value>
60        </property>
61    </bean>
62                 
63 </beans>

什么是bean装配?
bean 装配是指在Spring 容器中把bean组装到一起,前提是容器需要知道bean的依赖关系,如何通过依赖注入来把它们装配到一起。

什么是bean的自动装配?
Spring通过Bean Factory中注入的方式自动搞定bean之间的依赖关系,这意味着容器不需要和配置,能通过bean工厂自动处理bean之间的协作。

Spring自动装配bean有哪些方式?
在Spring中,由容器负责把需要相互协作的对象引用赋予各个对象,使用autowire来配置自动装载模式。
在Spring框架xml配置中有5种自动装配:
no:默认的方式是不进行自动装配的,通过手工设置ref属性来进行装配bean
byName:通过bean的名称进行自动装配,如果一个bean的property与另外一bean的name相同,就进行自动装配。
byType:通过参数的数据类型进行自动装配
constructor:利用构造函数进行装配,并且构造函数的参数通过byType进行装配
autodetect:自动装配,如果有构造方法,通过construct的方式自动装配,否咋使用buType的方法自动装配
使用@Autowired注解自动装配的过程是咋样的?
使用@Autowired注解来自动装配指定的bean。在使用@Autowired注解之前需要在Spring配置文件进行配置<context:annotation-config/>

在启动spring IoC时,容器自动装载了一个AutowiredAnnotationBeanPostProcessor后置处理器,当容器扫描到@Autowied、@Resource或@Inject时,就会在IoC容器自动查找需要的bean,并装配给该对象的属性。在使用@Autowired时,首先在容器中查询对应类型的bean:

如果查询结果刚好为一个,就将该bean装配给@Autowired指定的数据;
如果查询的结果不止一个,那么@Autowired会根据名称来查找;
如果上述查找的结果为空,那么会抛出异常。解决方法时,使用required=false。

自动装配有哪些局限性?

重写:需要重写自动装配

基本数据类型:不能自动装配简单的属性,如基本数据类型,String字符串,类

模糊特性:自动装配不如显示装配精确,建议使用显示装配

Spring面向切面编程(AOP)

什么是AOP?

OOP(Object-Oriented Programming)面向对象编程,允许开发者定义纵向的关系,但并适用于定义横向的关系,导致了大量代码的重复,而不利于各个模块的复用。

AOP(Aspect-Oriented Programming),用于将那些与业务无关,但却对多个对象产生影响的公共行为和逻辑,抽取并且封装为一个可重用的模块,这个模块被称为切面(Aspect),减少系统中的重复代码,降低了模块间的耦合度,同时提高了系统的可维护性。

Spring AOP and Aspectj AOP 有什么区别?AOP有哪些实现方式?

AOP实现的关键在于 代理模式,AOP代理主要分为静态代理和动态代理。静态代理的代表为AspectJ;动态代理则以Spring AOP为代表。

(1)AspectJ是静态代理的增强,所谓静态代理,就是AOP框架会在编译阶段生成AOP代理类,因此也称为编译时增强,他会在编译阶段将AspectJ(切面)织入到Java字节码中,运行的时候就是增强之后的AOP对象。

(2)Spring AOP使用的动态代理,所谓的动态代理就是说AOP框架不会去修改字节码,而是每次运行时在内存中临时为方法生成一个AOP对象,这个AOP对象包含了目标对象的全部方法,并且在特定的切点做了增强处理,并回调原对象的方法

JDK动态代理和CGLIB动态代理的区别?

 

JDK动态代理主要是针对类实现了某个接口,AOP则会使用JDK动态代理,他基于反射机制的实现,生成一个实现同样接口的一个代理类,然后通过重写方法的方式,实现对代码的增强。

而如果某个类没有实现接口,AOP则会使用CGLIB代理,他的底层原理是基于asm第三方框架通过修改字节码生成一个子类,然后重写父类的方法,实现对代码的增强,从而实现AOP。CGLIB是通过继承的方式做的动态代理,因此如果某个类被标记为final,那么它是无法使用CGLIB做动态代理的。

 

如何理解Spring种的代理?

将Advice应用于目标对象后创建的对象成为代理。在客户端的情况下,目标对象和代理对象是相同的。   Advice + Target Object = Proxy

Aop在Spring中的作用

提供声明式事务;允许用户自定义切面

横切关注点:跨越应用程序多个模块的方法或功能。即是,与我们业务逻辑无关的,但是我们需要关注的部分,就是横切关注点。如日志,安全,缓存,事务等等。

切面(ASPECT):横切关注点 被模块化的特殊对象。它是一个类

通知(Advice):切面必须要完成的工作。是类中的一个方法

目标(Target):被通知对象

代理(Proxy):向目标对象应用通知之后创建的对象

切入点(PointCut):切面通知 执行的“地点”的定义

连接点(JointPoint):与切入点匹配的执行点

 

 

在Spring AOP 中,关注点和横切关注的区别是什么?在spring aop中 concern和cross-cutting concern的不同之处

 关注点(concern) 是应用中一个模块的行为,一个关注点可能会被定义成一个我们想实现的一个功能

横切关注带你(cross-cutting concern)是一个关注点,此关注点是整个应用都会使用的功能,并且影响整个应用,比如日志,安全和数据传输,几乎应用的每个模块都需要的功能。因此这些都属于横切关注点。

Spring通知有哪些类型?


在AOP术语中,切面的工作被称为通知,实际上是程序执行时要通过SpringAOP框架触发的代码段。

Spring切面可以应用5种类型的通知:

       1.前置通知(Before):在目标方法被调用之前通知功能;

       2.后置通知(After):在目标方法完成之后调用通知,此时不会关心方法的输出是什么;

       3.返回通知 (After-returning):在目标方法成功之后调用通知;

       4.异常通知(After-throwing):在目标方法抛出异常之后调用调用通知

       5.环绕通知(Around):通知包裹了被通知的方法,在被统治的方法调用之前和调用之后执行自定义的行为

同一个aspect,不同advice的执行顺序:

①没有异常情况下的执行顺序:

around before advice
before advice
target method 执行
around after advice
after advice
afterReturning
②有异常情况下的执行顺序:

around before advice
before advice
target method 执行
around after advice
after advice
afterThrowing:异常发生
java.lang.RuntimeException: 异常发生

什么是切面Aspect?

切面时通知(advice)和pointcount(切点)的结合。Spring AOP 就是负责实施切面的框架,它将切面所定义的横切逻辑编织到切面所指定的连接点中。

AOP的工作重心在于如何将增强编织目标对象的连接点上,这里包含两个工作:

            如何通过pointcut和advice定位到特定的joinpoint上

            如何在advice中编写切面代码

Spring注解

1.什么是基于Java的Spring注解配置?

基于Java的配置,允许你在少量的java注解的帮助下,进行你的大部分Spring配置而非通过XML文件。

以@Configuration 注解为例,它用来标记类可以当作一个bean的定义,被Spring IOC 容器使用。

另一个例子时@Bean注解,它表示此方法将要返回一个对象,作为一个bean注册进Spring应用上下文。

@Configuration
public class StudentConfig {
      @Bean
      public StudentBean myStudent() {
      return new StudentBean();
}
}

2.怎样开启注解装配?

我们必须在Spring配置文件中配置<context:annotation-config/>元素。

 

3.@Component,@Controller,@Repository,@Service 有何区别?

   4个注解的意思就是说明这个类被Spring接管了,注册到了容器中,

 组件类注解

@Component:实现Bean组件的定义

@Repository :用于标注DAO类

@Service :用于标注业务类

@Controller :用于标注控制器类

 

装配bean时常用的注解

@Autowired 

@Resource注解和@Autowired注解类似,都用来声明需要自动装配的bean,区别在于@Autowired是类型驱动的注入,而@Resource是名称驱动的注入,所以前者存在多bean问题,而后者,只要保证bean命名唯一就不会出现多bean的问题。

       关于@Resource注解,有3种情况:(https://baijiahao.baidu.com/s?id=1722572804842285538&wfr=spider&for=pc)

          1.Resource中指定name属性

          2.不指定name属性,按照变量名查找进行装配

          3.使Resource注解按照类型查找进行装配

@PostConstruct  和 @PreDestory  方法   实现初始化和销毁bean之前进行的操作

@Component ,@Configuration , @Bean:

简单介绍就是Spring的官方团队说@Component可以替代 @Configuration注解,其实事实上我们看源码也可以发现。虽然是说可以替代但是两个注解之间还是有区别的。Bean注解主要用于方法上,有点像工厂方法,当你使用了@Bean注解,我们可以连续使用多种定义bean时用到的注解,比如说用@Qualifier注解定义工厂方法的名称,用@Scope注解定义该bean的作用域范围,比如说是singleton还是prototype等等。

Spring中新的Java配置支持的核心其实就是@Configuration注解的类。这些类主要包括@Bean注解的方法来为Spring 的IoC容器管理的对象定义实例,配置和初始化逻辑。使用@Configuration来注解类表示类可以被Spring的IoC容器所使用,作为bean定义的资源。

 

核心注解

@Required   此注解用于bean 的setter方法上。表示此属性是必须的,必须在配置阶段注入,否则会抛出BeanlnitializationException

@Autowired   可用于为类的属性,构造器,方法进行注值,此注解经常用法是将此注解用于setter上这样可以在setter方法中添加自定义代码。当然也可以去掉set,也能够自动装配

@Qualifier    此注解是和@Autowired 一起使用的。@Qualifiler可以被用在方法的参数上。当上下文有几个相同类型的bean,使用@Autowired无法区分要绑定的bean,此时可以使用@Qualifier来指定名称

@ComponentScan此注解一般和@Configuration注解一起使用,指定Spring扫描注解的package。

@Lazy  此注解表示此bean只有在第一次被使用的时候才会被创建和初始化。也可以用在被@Configuration注解的类上,表示其中所有被@Bean注解的方法都会延迟初始化。

@Value 此注解使用在字段,构造器参数和方法参数上。    @Qualifier(value=“cat111”)

 

@RequestMapping 

      @Controller注解用来把一个类定义为Controller。

     @RequestMapping注解用来把web请求映射到相应的处理函数。

      @Controller和@RequestMapping结合起来完成了Spring MVC请求的派发流程。

@RequestMapping的用法

参数说明  value:定义处理方法的请求的URL地址。(重点)

 有两种标注方式,一种是标注在类级别上,一种是标注在方法级别上。标注在方法上时,value表示访问该方法的URL地址,标注在类上,value相当于一个命名空间,即访问该Controller下的任意方法都需要带上这个命名空间,例如:

@Controller
@RequestMapping("/example")
public class ExampleController {

       @RequestMapping
       public String execute(){
       return "example_page";
}

       @RequestMapping("/todo")
       public String doSomething(){
       return "example_todo_page";
}

}

1:/example.action:执行的是 execute() 方法。execute() 方法的 @RequestMapping 注解缺省 value 值,在这种情况下,当访问命名空间时默认执行的是这个方法。方法级别上的 @RequestMapping 标注是必须的,否则方法无法被正确访问。

2:/example/todo.action执行的是 doSomething() 方法。类级别上的 @RequestMapping 标注不是必须的,在不写的情况下,方法上定义的 URL 都是绝对地址,否则,方法上定义的 URL 都是相对于它所在的 Controller 的。

 Spring数据访问

 1.解释对象/关系映射集成模块

       spring通过提供ORM模块,支持我们在直接JDBC之上使用一个对象/关系映射 映射(ORM)工具。

2.在Spring框架中如何更有效的使用JDBC?

       JDBC可以在Spring框架提供的模板类的帮助下更有效的被使用,这个模板叫做 JDBC Template

3.spring JDBC API 中存在哪些类?

       Jdbc Template

       Simple Jdbc Template

       NamedParameter Jdbc Template

       SimpleJdbcInsert

       Simple JdbcCall

4.JdcTemplate是什么?

JdbcTemplate   类提供了方法解决比如把数据库数据转变成基本数据类型或对象,执行写好的或可调用的数据库操作语句,提供自定义的数据错误处理。

 

Spring支持的事务管理模型,spring事务实现方式有哪些?

编程式事务管理:这意味你通过编程的方式管理事务,给你带来极大的灵活性,但是难维护。

声明式事务管理:这意味着你可以将业务代码和事务管理分离,你只需用注解和XML配置来管理事务。

Spring事务的实现方式和实现原理?

Spring事务的本质其实就是数据库对事务的支持,没有数据库的事务支持,spring是无法提供事务功能的。真正的数据库层的事务提交和回滚是通过binlog或者redo log实现的。

 

 

11. 说一下Spring的事务传播行为
spring事务的传播行为说的是,当多个事务同时存在的时候,spring如何处理这些事务的行为。

① PROPAGATION_REQUIRED:如果当前没有事务,就创建一个新事务,如果当前存在事务,就加入该事务,该设置是最常用的设置。

② PROPAGATION_SUPPORTS:支持当前事务,如果当前存在事务,就加入该事务,如果当前不存在事务,就以非事务执行。

③ PROPAGATION_MANDATORY:支持当前事务,如果当前存在事务,就加入该事务,如果当前不存在事务,就抛出异常。

④ PROPAGATION_REQUIRES_NEW:创建新事务,无论当前存不存在事务,都创建新事务。

⑤ PROPAGATION_NOT_SUPPORTED:以非事务方式执行操作,如果当前存在事务,就把当前事务挂起。

⑥ PROPAGATION_NEVER:以非事务方式执行,如果当前存在事务,则抛出异常。

⑦ PROPAGATION_NESTED:如果当前存在事务,则在嵌套事务内执行。如果当前没有事务,则按REQUIRED属性执行。

spring 有五大隔离级别,默认值为 ISOLATION_DEFAULT(使用数据库的设置),其他四个隔离级别和数据库的隔离级别一致:

ISOLATION_DEFAULT:用底层数据库的设置隔离级别,数据库设置的是什么我就用什么;
ISOLATION_READ_UNCOMMITTED:未提交读,最低隔离级别、事务未提交前,就可被其他事务读取(会出现幻读、脏读、不可重复读);
ISOLATION_READ_COMMITTED:提交读,一个事务提交后才能被其他事务读取到(会造成幻读、不可重复读),SQL server 的默认级别;
ISOLATION_REPEATABLE_READ:可重复读,保证多次读取同一个数据时,其值都和事务开始时候的内容是一致,禁止读取到别的事务未提交的数据(会造成幻读),MySQL 的默认级别;
ISOLATION_SERIALIZABLE:序列化,代价最高最可靠的隔离级别,该隔离级别能防止脏读、不可重复读、幻读。
脏读 :表示一个事务能够读取另一个事务中还未提交的数据。比如,某个事务尝试插入记录 A,此时该事务还未提交,然后另一个事务尝试读取到了记录 A。

不可重复读 :是指在一个事务内,多次读同一数据。

幻读 :指同一个事务内多次查询返回的结果集不一样。比如同一个事务 A 第一次查询时候有 n 条记录,但是第二次同等条件下查询却有 n+1 条记录,这就好像产生了幻觉。发生幻读的原因也是另外一个事务新增或者删除或者修改了第一个事务结果集里面的数据,同一个记录的数据内容被修改了,所有数据行的记录就变多或者变少了。

 

posted @ 2022-04-06 12:43  远乡人  阅读(112)  评论(0编辑  收藏  举报