Learning the fourth day spring

Spring Day Lecture

Content Today

  1. Spring 's transaction management
  2. Spring and MyBatis Integration Framework

 

1.  the Spring transaction management

1.1.  What business is ?

 

When the operation of the database (CRUD), if the simultaneous operation of multiple data, we expect the business, either all succeed, or all fail. This situation is called a transaction.

 

A transfer to B .

The first step, after deducting A king account of the amount to be transferred

The second step, increase the B amount monarch account

 

Transaction: single logical operation unit refers to the collection of

1.2.  The Spring transaction control, we must be clear of

 

1.JavaEE system stratified development, the transaction is located in the business layer , so under normal circumstances we use proxy affairs, general on hierarchical design business layer .

2.spring framework provides us with a set of transactions control application program interfaces ( API ) .

3.spring transaction control are based on AOP , and both can be achieved using a programmed way, you can also use the configuration implementation. The focus of our study is the use configuration to achieve.

 

1.3.  Case leads to problems

Demand : From the ID of 10086 to 10010 ID account to account transfer 1000 dollars.

 

Data preparation: the Account table (account):

-------------------------

ID        BALANCE

-------------------------

10010       0

10086    1000

Design a table Account

CREATE TABLE `t_account` (

  `id` int(11) NOT NULL AUTO_INCREMENT,

  `balance` int(11) DEFAULT NULL,

  PRIMARY KEY (`id`)

) ENGINE=InnoDB AUTO_INCREMENT=10087 DEFAULT CHARSET=utf8;

Write Transfer Case

1.4.  Transfer Case

 

 

 

Conclusion : The above case analysis based on , transaction management should be in Service processing layer

1.5.  Database concurrency problems

 

What is a database concurrency problems?

 

Concurrency: multiple clients simultaneously access a database in a data (spike)

 

 

Database access can have multiple clients, if multiple clients concurrently access the same database resources , if not taken the necessary quarantine measures will lead to all kinds of concurrency problems, undermine the integrity of the data.

The problem is reduced to 5 categories

It includes 3 class data read problem (dirty read, non-repeatable read, phantom read)

And 2 class data update problems (lost updates the first category, the second category lost updates). Figure

1.5.1.  The first lost update

Two transactions update the same data, if a transaction commits, the other transaction is rolled back, the first update transaction will be rolled back

 

1.5.2.  The second category lost updates

Multiple transactions simultaneously reading the same data, and to complete their transaction commits, the commit transaction resulting in a final front cover all changes to the data transaction

 

 

1.5.3.  Dirty read

The second query to the transaction data to update the first uncommitted transaction, a second transaction performed according to the data, but the first transaction is rolled back, the second transaction operations dirty

 

 

1.5.4.  Magic Reading

A transaction query to the new data another transaction has been submitted, resulting in inconsistent data multiple queries

 

1.5.5.  Non-repeatable read

A transaction query to another transaction has modified the data, inconsistent data results in multiple queries

 

 

 

1.6.  Database transaction isolation level

Question: If the above-mentioned problems in theory that should be how to solve?

 

A: Generally , the database will handle some transaction concurrency problems, the database provides a different transaction isolation level to deal with different transaction concurrency issues, transaction isolation level is defined as follows:

Isolation Levels

Explanation

READ_UNCOMMITED

允许你读取还未提交的改变了的数据。可能导致脏、幻、不可重复读(相当于没有做任何事务隔离)

READ_COMMITTED

允许在并发事务已经提交后读取。可防止脏读,但幻读和 不可重复读仍可发生(ORACLE默认级别)

REPEATABLE_READ

对相同字段的多次读取是一致的,除非数据被事务本身改变。可防止脏、不可重复读,但幻读仍可能发生。(MYSQL默认级别)

SERIALIZABLE

完全服从ACID的隔离级别,确保不发生脏、幻、不可重复读。这在所有的隔离级别中是最慢的,它是典型的通过完全锁定在事务中涉及的数据表来完成的。(ORACLE支持)

 

针对不同隔离级别可以解决的的如下五类问题

 

 

1.6.1. 解决丢失更新的方案 

 

数据库表数据加锁

 

1,悲观锁

(1) 在操作当前数据的事务开启事务就使用for update 锁住当前数据

(2) Hibernate和MyBatis都有悲观锁对应的解决方案

 

 

2,乐观锁

(1) 为表添加一个version字段。当前事务操作的时候都会比对当前事务情况的多次操作的版本号是否一致,如果不一致认为数据已经被更新

(2) Hibernate和MyBatis都有乐观锁对应的解决方案

 

1.7. Spring对事务的支持

  1. 为什么需要使用Spring是事务

答:使用Spring是事务代理,可以配置一次,不用重复编写事务处理代码!!

 

 

Spring框架针对事务处理提供专门的解决方案

Spring的事务管理主要包括3个接口

Spring事务处理接口

描述

TransactionDefinition

封装事务的隔离级别超时时间,是否为只读事务和事务的隔离级别和传播规则等事务属性,可通过XML配置具体信息

PlatformTransactionManager

根据TransactionDefinition提供的事务属性配置信息,创建事务。事物管理器

TransactionStatus

封装了事务的具体运行状态。比如,是否是新开启事务,是否已经提交事务,设置当前事务为rollback-only

 

 

1.7.1. TransactionDefinition

该接口主要定义了:事务的传播行为(规则)事务的隔离级别获得事务信息的方法。所以在配置事务的传播行为,事务的隔离级别已经需要获得事务信息时,可以通过查阅该类的代码获得相关信息。

 

TransactionDefinition源码

public interface TransactionDefinition {

 

     //事务的传播行为

int PROPAGATION_REQUIRED = 0;

 

int PROPAGATION_SUPPORTS = 1;

 

int PROPAGATION_MANDATORY = 2;

 

int PROPAGATION_REQUIRES_NEW = 3;

 

int PROPAGATION_NOT_SUPPORTED = 4;

int PROPAGATION_NEVER = 5;

int PROPAGATION_NESTED = 6;

    //事务的隔离级别

int ISOLATION_DEFAULT = -1;

 

int ISOLATION_READ_UNCOMMITTED = Connection.TRANSACTION_READ_UNCOMMITTED;

 

int ISOLATION_READ_COMMITTED = Connection.TRANSACTION_READ_COMMITTED;

 

int ISOLATION_REPEATABLE_READ = Connection.TRANSACTION_REPEATABLE_READ;

 

int ISOLATION_SERIALIZABLE = Connection.TRANSACTION_SERIALIZABLE;

    //事务超时管理

int TIMEOUT_DEFAULT = -1;

 

//获得事务信息

int getPropagationBehavior();

 

int getIsolationLevel();

 

int getTimeout();

 

boolean isReadOnly();

 

String getName();

 

}

 

 

1.7.1.1. 事务传播规则

SpringTransactionDefinition接口中定义了七种事务传播规则,规定了事务方法和事务方法发生嵌套调用时事务该如何进行传播

 

事务传播规则类型

描述

PROPAGATION_REQUIRED

如果当前存在事务,则加入该事务;如果当前没有事务,则创建一个新的事务(最常用操作)-Spring默认使用的就是此规则

PROPAGATION_REQUIRES_NEW

创建一个新的事务,如果当前存在事务,则把当前事务挂起

PROPAGATION_SUPPORTS

如果当前存在事务,则加入该事务;如果当前没有事务,则以非事务的方式继续运行

PROPAGATION_NOT_SUPPORTED

以非事务方式运行,如果当前存在事务,则把当前事务挂起

PROPAGATION_NEVER

以非事务方式运行,如果当前存在事务,则抛出异常

PROPAGATION_MANDATORY

如果当前存在事务,则加入该事务;如果当前没有事务,则抛出异常

PROPAGATION_NESTED

如果当前存在事务,则创建一个事务作为当前事务的嵌套事务来运行;如果当前没有事务,则该取值等价于TransactionDefinition.PROPAGATION_REQUIRED

 

1.7.2. PlatformTransactionManager事务管理器

Spring的事务管理:

1PlatformTransactionManager:接口统一抽象处理事务操作相关的方法;

1):TransactionStatus getTransaction(TransactionDefinition definition)

根据事务定义信息从事务环境中返回一个已存在的事务,或者创建一个新的事务,并用TransactionStatus描述该事务的状态。

ü 2):void commit(TransactionStatus status)

根据事务的状态提交事务,如果事务状态已经标识为rollback-only,该方法执行回滚事务的操作。

ü 3):void rollback(TransactionStatus status)

将事务回滚,当commit方法抛出异常时,rollback会被隐式调用

 

2,在使用spring管理事务的时候,首先得告诉spring使用哪一个事务管理器,使用不同的框架(JdbcTemplate,MyBatis,Hibernate/JPA )使用事务管理器都不同

 

 

1.7.2.1. PlatformTransactionManager事物管理器的继承体系图

 

3,常用的事务管理器:

   DataSourceTransactionManager:使用JDBC,MyBatis的事务管理器;

 

 

1.8. Spring事务的配置

Spring支持编程式事务管理和声明式事务管理。

  1. 编程式事务管理:事务和业务代码耦合度太高。

 

  1. 明式事务管理:侵入性小,把事务从业务代码中抽离出来,使用AOP配置到配置文件中,提高维护性。

1.8.1. 声明式事务管理-xml方式配置

1.8.1.1. 准备配置文件

在配置文件中引入新的命名空间 tx

<beans xmlns="http://www.springframework.org/schema/beans"

xmlns:p="http://www.springframework.org/schema/p"

xmlns:context="http://www.springframework.org/schema/context"

xmlns:aop="http://www.springframework.org/schema/aop"

xmlns:tx="http://www.springframework.org/schema/tx"

xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

xsi:schemaLocation="http://www.springframework.org/schema/beans

    http://www.springframework.org/schema/beans/spring-beans.xsd

    http://www.springframework.org/schema/context

    http://www.springframework.org/schema/context/spring-context.xsd

    http://www.springframework.org/schema/aop

    http://www.springframework.org/schema/aop/spring-aop.xsd

    http://www.springframework.org/schema/tx

    http://www.springframework.org/schema/tx/spring-tx.xsd

    ">

1.8.1.2. 配置事物管理器-DataSourceTransactionManager

Spring对象事务的支持,必须先配置事务管理器,事务管理器已经封装了事务的具体的处理

DataSourceTransactionManager

使用JDBC,MyBatis的事务管理器;(当前案例使用的SpringJDBC操作,所以配置这个)

<!-- 1,配置事务管理器(应根据情况使用合适的事务管理器) -->

<bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">

<!-- 注入dataSource -->

<property name="dataSource" ref="dataSource"/>

</bean>

<!--

1、切入点(Pointcut):在哪些类,哪些方法上切入(where);

2、增强(Advice):早期翻译为通知,在方法执行的什么时机(when:方法前/方法后/方法前后)做什么(what:增强的功能);

3、切面(Aspect):切面=切入点+通知,通俗点就是:什么时机,什么地点,做什么!

4、织入(Weaving):把切面加入到对象,并创建出代理对象的过程。(该过程由Spring来完成)。

 WWW 原则 :

 where : 在什么地方切事务

 what : 干什么(切事务)

 when : 时机(在方法前或者后)

 -->

 

<!-- 事务相关的配置 : 使用AOP面向切面编程(切事务) : 使用 tx: 标签  -->

<!-- tx:advice : 配置事物的标签

id : 唯一标识

transaction-manager : 需要用到的事物管理器

 -->

<!-- 2,配置管理事务的“增强” :环绕通知-->

<tx:advice id="txAdvice" transaction-manager="txManager">

<tx:attributes>

<!-- 配置要切的方法 : trans (默认使用的是环绕通知) -->

<tx:method name="trans"/>

</tx:attributes>

</tx:advice>

 

<!-- 3,面向切面 :  -->

<aop:config >

<!-- 切入点 : where -->

<aop:pointcut expression="execution ( * cn.zj.spring.service..*.*(..))" id="pt"/>

<!-- 配置切面  切面 = 切入点 + 通知

advice-ref 通知的引用

pointcut-ref 切入点的引入

 -->

<aop:advisor  advice-ref="txAdvice"  pointcut-ref="pt" />

<!-- 织入(Weaving):把切面加入到对象,并创建出代理对象的过程。(该过程由Spring来完成) -->

</aop:config>

1.8.1.3. 事物方法的属性细节配置

事务方法属性:

事务方法属性

描述

name

匹配到的方法模式

read-only

如果为true,开启一个只读事务,只读事务的性能较高,但是不能再只读事务中,使用DML

isolation

代表数据库事务隔离级别(就使用默认)

DEFAULT:spring使用数据库默认的事务隔离级别;

no-rollback-for

如果遇到的异常是匹配的异常类型,就不回滚事务

rollback-for

如果遇到的异常是指定匹配的异常类型,才回滚事务;spring默认情况下,spring只会去回滚RuntimeException及其子类,不会回滚ExceptionThowable

propagation

事务的传播方式(当一个方法已经在一个开启的事务当中了,应该怎么处理自身的事务)

  1,REQUIRED(默认的传播属性):如果当前方法运行在一个没有事务环境的情况下,则开启一个新的事务,如果当前方法运行在一个已经开启了的事务里面,把自己加入到开启的那个事务中

  2,REQUIRES_NEW:不管当前方法是否运行在一个事务空间之内,都要开启自己的事务

 

timeout

事务处理的超时时间,默认事物管理自动处理 ,可以手动配置

 

 

<tx:advice id="txAdvice" transaction-manager="txManager">

<tx:attributes>

 

<!-- <tx:method>

name : 需要切面的方法

isolation : 事务的隔离级别 DEFAULT 使用当前数据库默认的隔离级别,不同数据库隔离级别不同(可以不配置)

propagation : 事物的传播规则 ,默认使用 REQUIRED

read-only : 是否是只读事务, DQL配置即可

 -->

<!-- 一般DML操作才需要事务,DQL查询操作是不需要事物

* 通配符

 -->

<!-- 所有以前缀开都的方法都认为是 查询方法,就不切入事物 -->

<tx:method name="get*" read-only="true"/>

<tx:method name="select*"  read-only="true" />

<tx:method name="find*"  read-only="true"/>

<tx:method name="query*"  read-only="true"/>

<tx:method name="list*"  read-only="true"/>

 

<!-- 非查询(DQL)方法: DML操作,需要事务管理 -->

<tx:method name="*" />

</tx:attributes>

</tx:advice>

1.8.2. 声明式事务管理-基于注解配置

Spring声明式事务也支持 注解

1.8.2.1. applicationContext.xml配置文件

<!-- 1,配置事务管理器(应根据情况使用合适的事务管理器) -->

<bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">

<!-- 注入dataSource -->

<property name="dataSource" ref="dataSource"/>

</bean>

 

<!-- 开启注解驱动配置事务

编写此标签:Spring底层就支持注解配置事物,并且已经配置好事物管理器

 -->

<tx:annotation-driven transaction-manager="txManager"/>

1.8.2.2. AccountServiceImpl 业务层代码

@Service

/* @Transactional

 * 贴上此当前类已经被Spring事务管理

 * 注意: @Transactional 只能对当前贴的Service类有效

 *  常用属性 :

 *   isolation=Isolation.REPEATABLE_READ,  隔离级别

propagation=Propagation.REQUIRED,传播规则

readOnly=true 是否只读事务

 *  

 */@Transactional(isolation=Isolation.DEFAULT,propagation=Propagation.REQUIRED)

public class AccountServiceImpl implements AccountService{

@Autowired

private AccountDao dao;

 

public void trans(Integer transOutId,

Integer transInId, Integer money) {

dao.tranOut(transOutId, money);

System.out.println(1 / 0);// 模拟断电

dao.tranIn(transInId, money);

}

//单独为某一个方法配置具体的事物细节:如查询方法,事物是只读的

@Transactional(readOnly=true)

public Object getUser() {

//查询操作

return null;

}

@Transactional(readOnly=true)

public List<Object> getUsers() {

//查询操作

return null;

}

}

 

1.8.3. 事物配置的注解和XML配置的选择

Xml配置 : 代码清晰,配置量少,容易维护

注解配置 : 侵入代码,每个Service层类都得配置,针对不同的方法还得配置事务细节:如查询方法配置只读操作,不容易维护

建议选择xml配置

 

 

 

 

 

2. 小结

Spring框架出现原因?

 

早期企业级开发组件(框架) EJB (重量级)不好用

 

 

音乐博士,计算机大牛

 

 

觉得ejb 不好,写了一本书各种吐槽抨击 ejb

 

顺便写了一个轻量级 一站式 企业框架 spring

 

 

 

2.1. Spring 核心作用

解耦 (降低程序代码与代码的直接依赖关系)

 

2.2. 核心功能

Spring容器-下面所有操作都在Spring 容器中完成,Spring就是项目对象的管家

  1. IOC :控制反转(将对象的创建权交给Spring管理)

(1) Xml 配置

① <bean id/name=xxx class = 类的全限定名 scope=作用范围 init-mehtod=初始化方法destory-mehtod=销毁方法>

② Spring容器中读取bean对象

(2) 注解配置 -贴在类上即可

① @Component  通用组件扫描创建

② @Controller 表现层(SpringMVC 专用)

③ @Service 业务层专用

④ @Repository 持久层/DAO/Mapper 专用

⑤ @Scope 作用范围

⑥ @PostConstrcut 初始化方法

⑦ @PreDestory 销毁方法

  1. DI : 依赖注入(将对象的属性赋值,对象依赖关系维护交给Spring

(1) XML配置

① <property name=’’  value/ref=’’> 属性注入

② <constructor-arg  name=参数名 value/ref=’’ >

③ P 命名空间

1) <bean id =xx class =Xxxx p:属性名= p:属性名-ref=引用类型>

(2) 注解配置

① Spring框架制定

1) @Autowired 默认按照类型注入  

  1. 可以贴在 字段(成员编写)set方法,构造函数

2) @Qualifier 从多个相同类型中通过id指定唯一的那个bean

② JavaEE 官方指定

1) @Resource(name=beanid)

  1. AOP :面向切面编程

(1) AOP 底层原理-Java动态代理

① JDK动态代理 : 只能有接口的类型进行代理

② CGLIB代理 :即可代理有接口类,有可以代理没有接口的

(2) 专业术语

① JoinPoint 连接点(方法)

② PointCut 切入点 (某一类方法,规则)

③ Advice 通知/增强

④ Aspect 切面 = 切入点+通知

⑤ Weaving 织入(Spring自动完成)

  1. Spring事务管理

(1) 配置事务管理器

① JDBC/MyBatis  ---->DataSourceTransactionManager

(2) 事务的隔离级别 4

(3) 事务的传播规则(行为) 7

(4) 是否是只读事务

(5) 使用AOP 将事务切入到 业务层

  1. Spring-Jdbc (了解)

(1)  jdbcTemplate 模板类

① Update 更新方法(update,insert,delete

② queryForObject : 单行查询

③ Query : 多行查询

  1. Spring-test
  2. SpringMVC

转载于:https://www.cnblogs.com/ki16/p/11051370.html

Guess you like

Origin blog.csdn.net/weixin_34270865/article/details/92855408