Spring框架一

Spring框架一

一、Spring Bean的作用域

一、名词解释

1、在Spring中,可以在元素的scope属性里设置bean的作用域,以决定这个bean是单实例的还是多实例的。
2、默认情况下,Spring只为每个在1OC容器里声明的bean创建唯一一个实例,整个1OC容器范围内都能共享该实例:所有后续的 getBean()调用和 bean引用都将返回这个唯一的bean实例。该作用域被称为singleton,它是所有bean的默认作用域。

类别 说明
singleton 在SpringlOC容器中仅存在一个Bean实例,Bean以单实例的方式存在prototype 每次调用getBean)时都会返回一个新的实例
prototype 每次调佣getBean()时都会返回一个新的实例
request 每次HTTP请求都会创建一个新的Bean,该作用域仅适用于WebApplicationContext 环境
session 用一个HTTP Session共享一个Bean,不同的HTTP Session使用不同的Bean,该作用域仅适用于WebApplicationContext 环境

当Bean的作用域为单例时,Spring会在IOC容器对象创建时就创建Bean的对象实例。

二、代码示例

代码示例:

public class SprBean {
    private int id;
    private int age;
    private String sex;

    public SprBean() {
        System.out.println("SprBean无参对象被创建了");
    }

    public SprBean(int id, int age, String sex) {
        this.id = id;
        this.age = age;
        this.sex = sex;
        System.out.println("SprBean有参对象被创建了");
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public String getSex() {
        return sex;
    }

    public void setSex(String sex) {
        this.sex = sex;
    }
}

测试类

import com.demo.SprBean;
import org.junit.Test;

public class SprBeanTest {
    //创建IOC容器对象
    AppliactionContext ioc = new ClassPathXmlAppliactionContext("beans.xml");

    @Test
    public void test(){
        SprBean bs1 = (SprBean) ioc.getBean("sBean");
        SprBean bs2 = (SprBean) ioc.getBean("sBean");
        System.out.println(bs1 == bs2);
    }
}

文本类:beans.xml

<bean id="sBean" class="com.demo.SprBean" scope="singLeton">
    <propert name="id" value="2"></propert>
    <propert name="age" value="16"></propert>
    <propert name="sex" value="男"></propert>
</bean>

运行结果:

bean作用域为:singLeton

"C:\Program Files\Java\jdk1.8.0_171\bin\java.exe" "-javaagent:E:\JAVA\idea\IntelliJ IDEA  com.demo.Step1
SprBean无参对象被创建了
true   
    
Process finished with exit code 0

bean作用域为:prototype

"C:\Program Files\Java\jdk1.8.0_171\bin\java.exe" "-javaagent:E:\JAVA\idea\IntelliJ IDEA  com.demo.Step1
SprBean无参对象被创建了
SprBean无参对象被创建了
false  
    
Process finished with exit code 0

二、Spring支持的数据库事务

事务是用户定义的数据库序列,这些操作要么全做,要么全不做,是一个不可分割的工作单位

一、事务传播行为

一个方法运行在了一个开启事务的方法中时,当前方法是使用原来的事务还是开启一个新的事务!

spring定义了7种事务传播行为:

传播属性 描述
REQUIRED 如果有事务在运行,当前的方法就在这个事务内运行,否则,就启动一个新的事务,并在自己的事务内运行
REQUIRES_NEW 当前的方法必须启动新事务,并在它自己的事务内运行.如果有事务正在运行,应该将它挂起
SUPPORTS 如果有事务在运行,当前的方法就在这个事务内运行.否则它可以不运行在事务中.
NOT_SUPPORTE 当前的方法不应该运行在事务中,如果有运行的事务,将它挂起
MANEATORY 当前的方法必须运行在事务内部,如果没有正在运行的事务,就抛出异常
NEVED 当前的方法不应该运行在事务中,如果有运行的事务,就抛出异常
NESTED 如果有事务在运行,当前的方法就应该在这个事务的嵌套事务内运行.否则,就启动一个新的事务,并在它自己的事务内运行

事务传播属性可以在@Transactional注解的propagation属性中定义。

二、事务的特性

事务具有4个特性:原子性(Atomicity)一致性(Consistency)隔离性(Isolation)持续性(Durability)。这4个特性简称为ACID特性

  1. 原子性:事务是一个原子性质的操作单元,事务里面的对数据库的操作要么都执行,要么都不执行。
  2. 一致性:在事务开始之前和完成之后,数据都必须保持一致状态,必须保证数据库的完整性。也就是说,数据必须符合数据库的规则。
  3. 隔离性:一个事务的执行不能被其他事务干扰。即一个事务的内部操作及使用的数据对其他并发事务是隔离的,并发执行的各个事务之间不能互相干扰。
  4. 持久性:持久性也成为永久性,指一个事务一旦提交,它对数据库中数据的改变就应该是永久的。

三、事务隔离

一、事务并发问题

  1. 脏读:事务A读到了事务B更新但未提交的数据;
  2. 幻读:在两个事务对数据表同时修改时,事务A修改之后读取到事务B修改过的数据。
  3. 不可重复读:事务A对数据表第一次读取到数据后,事务B对该表数据进行修改,导致事务A再次读取数据时与第一次的数据不一致。

二、隔离级别

  1. 读未提交(Read Uncommitted):在该隔离级别,所有事务都可以看到其他未提交事务的执行结果。本隔离级别很少用于实际应用,因为它的性能也不比其他级别好多少。读取未提交的数据,也被称之为脏读(Dirty Read)

  2. 读已提交(Read Committed):这是大多数数据库系统的默认隔离级别(但不是MySQL默认的)。它满足了隔离的简单定义:一个事务只能看见已经提交事务所做的改变。这种隔离级别也支持所谓的不可重复读(NonrepeatableRead),因为同一事务的其他实例在该实例处理其间可能会有新的commit,所以同一select可能返回不同结果

  3. 可重复读(Repeatable Read):这是MySQL的默认事务隔离级别,同一事务的多个实例在并发读取数据时,会看到同样的数据。不过理论上,这会导致另一个棘手的问题:幻读(Phantom Read)。简单的说,幻读指当用户读取某一范围的数据行时,另一个事务又在该范围内插入了新行,当用户再读取该范围的数据行时,会发现有新的“幻影” 行。

  4. 可串行化(Serializable):这是最高的隔离级别,它通过强制事务排序,使之不可能相互冲突,从而解决幻读问题。简言之,它是在每个读的数据行上加上共享锁。在这个级别,可能导致大量的超时现象和锁竞争

三、隔离影响

四种隔离级别越往后越影响性能,如何选取根据业务需求而定。以下是四种隔离级别中对脏读、不可重复读、幻读的影响情况:

脏读 幻读 不可重复读
读未提交
读已提交 ×
可重复读 × ×
串行化 × × ×
posted @ 2022-05-29 19:48  の南归  阅读(41)  评论(0)    收藏  举报