Spring AOP :

Pointcut表达式: designators-指示器 wildcards-通配符 operators-操作符
wildcards: * -- 匹配任意数量的字符
+ -- 匹配制定类及其子类
..-- 一般用于匹配任意数的子包或参数
operator: && || !
Wildcards(通配符)
* 匹配任意数量的字符
+ 匹配指定类及其子类
.. 一般用于匹配任意数的子包或参数

Pointcut :切面表达式
designators:指示器,描述通过什么方式去匹配Java的那些方法
execution():匹配方法
匹配注解
@target()
@args()
@within()
@annotation()
within():匹配包/类型
this()/bean()/target():匹配对象
args():匹配参数

wildcards:通配符(*:匹配任意数量的字符;+匹配指定类及其子类;..:一般用于匹配任意数的子包或参数)
operators: 运算符(&&:与操作符;||或;!:非)

匹配包/类型 :
// 匹配ProductService类里头的所有方法
@Pointcut("within(com.imooc.service.ProductService)")
public void matchType() {
}

// 匹配com.imooc包及子包下所有类的方法
@Pointcut("within(com.imooc..*)")
public void matchPackage(){}

匹配对象:
1:this(包名):匹配AOP对象的目标对象指定类型的方法;
2:target(包名):匹配实现接口的目标对象的方法(不是AOP代理后的对象);
3:bean(包名):匹配所有以Service结尾的bean里头的方法;

/**
public class DemoDao implements IDao{}
*/
// 匹配AOP对象的目标对象为指定类型的方法,即DemoDao的aop代理对象的方法
@Pointcut("this(com.imooc.DemoDao)")
public void thisDemo() {}

// 匹配实现IDao接口的目标对象(而不是aop代理后的对象)的方法,这里即DemoDao的方法
@Pointcut("target(com.iommc.IDao)")
public void targetDemo() {}

// 匹配所有以Service结尾的bean里头的方法
@Pointcut("bean(*Service)")
public void beanDemo() {}

匹配参数
// 匹配任何以find开头而且只有一个Long参数的方法
@Pointcut("execution(* * ..find*(Long))")
public void argsDemo1() {}

// 匹配任何只有一个Long参数的方法
@Pointcut("args(Long)")
public void argsDemo2() {}

// 匹配任何find开头的而且第一个参数为Long型的方法
@Pointcut("execution(* *..find*(Long,..)")
public void argsDemo3() {}

// 匹配第一个参数为Long型的方法
@Pointcut("args(Long,..)")
public void argsDemo4() {}

匹配注解:
1:匹配方法级别的;
2:匹配类级别的;
3:匹配参数级别的;

@annotion:匹配方法级别的注解方法;
@within:匹配标注有Beta的类底下的方法;
@target:匹配标注有Repository的类底下的方法;
@args:匹配传入的参数类标注有Repository注解的方法;

示例 :
1: // 匹配方法标注有AdminOnly的注解的方法
@Pointcut("@annotation(com.imooc.demo.security.AdminOnly)")
public void annoDemo(){}

2: // 匹配标注有Beta的类地下的方法,要求的anntation的RetentionPolity级别的CLASS
@Pointcut("@within(com.google.common.annotations.Beta)")
public void annoWithDemo(){}

3: // 匹配标注有Repository的类地下的方法,要求的annotation的RetentionPolicy级别为RUNTIME
@Pointcut("@target(org.springframework.stereotype.Repository)")
public void annoTargetDemo() {}

4: //匹配传入的参数类标注有Repository注解的方法;
@Pointcut("@args(org.springframework.stereotype.Repository)")
public void annoArgsDemo(){}

@Before,表示在切点之前执行的插入的逻辑;
@Aspect切面类,标注界面类;
@Component,标注在类上,表示这个类交给spring托管;
execution表达式:
拦截方法:
@Pointcut("execution(public * com.imooc.service.*.*(..))");
拦截抛出的异常:
@Pointcut("exection(public * com.imooc.service.*.*(..) throws java.lang.IllegalAccessException)");
//匹配任何公共方法
@Pointcut("execution(public * com.imooc.service.*.*(..))")

//匹配com.imooc包及子包下Service类中无参方法
@Pointcut("execution(* com.imooc..*Service.*())")

//匹配com.imooc包及子包下Service类中的任何只有一个参数的方法
@Pointcut("execution(* com.imooc..*Service.*(*))")

//匹配com.imooc包及子包下任何类的任何方法
@Pointcut("execution(* com.imooc..*.*(..))")

//匹配com.imooc包及子包下返回值为String的任何方法
@Pointcut("execution(String com.imooc..*.*(..))")

//匹配异常
execution(public * com.imooc.service.*.*(..) throws java.lang.IllegalAccessException)

5种Advice:
1:@Before,前置通知;
2:@After(finally),后置通知,方法执行完成之后;
3:@AfterReturning,返回通知,成功执行之后执行;
4:@AfterThrowing,异常通知,抛出异常之后执行
5: @Around : 环绕通知

原理概述 : 织入的时机
1: 编译期(Aspectj)
2: 类加载时(Aspectj 5+)
3: 运行时(Spring AOP)
运行时织入:
1:静态代理与动态代理;
2:基于接口代理与基于继承代理;

代理模式;
组成:调用者,统一的接口、真实对象、代理者;
原理:通过接口,实现这样一个过程,在调用真实对象的时候,调用者并不直接与真实对象打交道,而是通过一个代理者与真实对象通信,代理者能够负责真实
对象的非业务逻辑,如日志管理、访问控制 、异常处理等,使得真实对象专注于业务逻辑的实现,不受非业务逻辑的干扰。
代理对象会把正真的业务逻辑委托给实际对象 而代理对象只会进行一写边缘的附加操作 这就是aop的实现原理.
代理对象调用目标对象的方法产生的异常需要抛出去,不能处理,因为代理对象的作用是对目标对象进行增强,不会对目标对象进行改变.

静态代理就是一个代理类根据被代理类的情况,被代理类有几个方法,代理类就需要有几个方法,每个方法都要对被代理类进行代理,这样会出现代码重复的情况,
如多个被代理方法其实前后需要执行的逻辑是一样的,但是静态代理还是需要为每个方法写一个代理方法,造成代码重复。动态代理根据放射得到被代理类执行的方
法和参数,避免了代码的重复。
静态代理的代码,静态代理的弊端:代理的对象越多.
JDK实现要点:
1类:java.lang.reflect.Proxy;
2接口:InvoctionHandler;
3只能基于接口进行动态代理.
动态代理实现时,需要的接口,InvocationHandler接口。
注意:在捕获异常之后,执行插入程序,然后还需要将异常在catch代码块内抛出去!

jdk运行期动态代理源码解析:其实就是真实类实现一个接口,我们再写一个类似于切面的类,实现invocationhandler接口且实现invoke方法,同时要保存真实类对象,
初始化时赋值对象,invoke方法中反射方式调用真是对象方法,在方法前后可以加上定制的逻辑,这个方法其实是动态代理对象调用的,动态代理对象是客户端通过动
态代理类实例化的,而动态代理类是真实对象方法执行前的运行期生成的.class类,这个类实现了和真实对象一样的接口,所以也有真实对象的方法,调用代理对象方
法时也就可以传入参数,然后代理对象再将方法和参数传递给invocationhandler的实例对象。

通过System.setProperties()可以设置保存jdk动态代理生成的字节码文件.

JDK与Cglib代理对比:
1:JDK只能针对有接口的类的接口方法进行动态代理;
2:Cglib基于继承来实现代理,无法对static、final类进行代理;
3:Cglib基于继承来实现代理,无法对private、static方法进行代理。

Cglib实现:
1:生成指定类对象的子类,也就是重写类中的业务函数。
2:执行回调函数,加入intercept()函数。
3:创建这个类的子类对象。
-----------------------------------------
反射技术实现;
methodProxy.invokeSuper();
JDK通过接口代理,所以只能代理实现接口的类的方法,而cglib通过继承实现代理,所以不能代理final类,也无法代理private和static方法.
无法对final类进行代理,因为final类不能被继承
关于Cglib无法对static类和方法进行代理:
单一的类是没有static修饰符的,只有静态类内部可以用static修饰;
对于static方法,它是属于类的,子类在不重写的情况下,是可以调用的,但是一旦重写了就无法调用了,普通的public方法可以通过super.method()调用,但是
static方法不行.

Spring如何创建代理bean?
JDK动态代理与Cglib代理是如何选用的?
-----------------------------
1:如果目标对象实现了接口,则默认采用JDK动态代理;
2:如果目标对象没有实现接口,则采用Cglib进行动态代理;
3:如果目标对象实现了接口,且强制Cglib代理,则使用Cglib代理;

继承JPARepository对数据操作实现自己的事务控制,@transactional会在子事务外层加一层事务控制,对事务整体进行控制,在方法执行前后判断事务需要进行回滚操作。
SpringBoot对缓存的一个控制:
1、引入依赖:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-cache</artifactId>
</dependency>
2、使用注解:
@Cacheable(cacheNames={"menu"})
public List<String> getMenuList(){
System.out.println("看看是不是只有第一次被调用");
return Arrays.asList("java","C++","PHP");
}

使用SpringAop的注意事项/坑
1: 不宜把重要的业务逻辑放到aop中处理;
2: 无法拦截static,final方法,private方法;
3: 无法拦截内部方法调用.

实现AOP的方法被方法内部调用时是不会走AOP的织入逻辑的,因为内部调用AOP方法的调用对象是this,而this不是增强的代理对象,所以不会走织入代码,解决方法
就是用ApplicationContent获取到增强的代理对象的bean,然后用这个bean来执行AOP方法,就可以走织入的代码逻辑了.
Spring Aop 的坑,无法拦截方法内部调用,因为内部调用是this调用的,而不是代理类调用的.
无法拦截内部调用的原因:aop通过代理实现的,而省略的this是指该对象,而不是代理后的对象
解决aop无法内部调用的问题:通过spring的ApplicationContext获取该类的对象,就是代理对象,使用代理对象去调用内部方法.
解决方法:通过ApplicationContext来获取代理bean,通过代理bean调用方法。

课程总结:

1.面向切面编程是对面向对象编程的补充,主要用于日志记录,权限验证,事务配置等功能。

2.使用aspectJ实现aop,aspectJ是一个面向切面的框架,它扩展了Java语言。

3.主要注解:

@Aspect 标注说明Java类是切面配置的类 由@Pointcut和@Advice组成

@Pointcut 描述在哪些类的哪些方法植入代码

@Advice表达在Pointcut表达式的什么时间执行

4. pointcut中的通配符,运算符,指示器(通过什么方式匹配植入的方法)

通配符:* 匹配任意数量的字符 +匹配指定类及其子类 ..一般用于匹配任意数的子包或参数

运算符:&&与操作符 || 或操作符 !非操作符

指示器:

a. @within 匹配包/类型

@Pointcut("within(com.imooc.service.ProductService")) //匹配ProductService类里的所有方法

@Pointcut("within(com.imooc..*)") //匹配com.imooc包及子包下所有类的方法

b. execution 表达式:方法的修饰符 返回值 包名.类名.方法(参数)

@Pointcut("execution(public * com.imooc.service.*Service.*(..))")//表示com.imooc.service包下以Service字符结尾的类中任意参数的所有方法

5.Advice 注明要在哪个切点执行什么操作,有几种方式

@Before("") //意思是在切点执行前执行

@After("") //意思是在切点执行前执行

@Around("") //表明在切点方法的前后都要执行该处理器方法

Spring事务 :
Spring事务管理接口:
PlatformTransactionManager:事务管理器
TransactionDefinition:事务定义信息(事务隔离级别、传播行为)(隔离、传播、超时、只读)
TransactionStatus:事务具体运行状态

事务管理器PlatformTransactionManager
Spring为不同的持久化框架提供了不同PlatformTransactionManager接口实现;
org.springframework.jdbc.datasource.DataSourceTransactionManager : 使用Spring JDBC或iBatis进行持久化数据时使用.
org.springframework.orm.hibernate3.HibernateTransactionManager : 使用Hibernate3.0版本进行持久化数据时使用.
org.springframework.orm.jpa.JpaTransactionManager : 使用JPA进行持久化时使用
org.springframework.jdo.JdoTransactionManager : 当持久化机制是Jdo时使用
org.springframework.transaction.jta.JtaTransactionManager : 使用一个JTA实现管理事务,在一个事务跨越多个资源时必须使用.
TransactionDefinition定义事务隔离级别
如果不考虑隔离性,会引发如下的安全问题:
1.脏读。
一个事务读取了另一个事务改写但还未提交的数据,如果这些数据被回滚,则读到的数据是无效的。
2.不可重复读。
在同一个事务中,多次读取同一数据返回的结果有所不同。
3.幻读。
一个事务读取了几行记录后,另一个事务插入一些记录,幻读就发生了。再后来的查询中,第一个事务就会发现有些原来没有的记录。

隔离级别的出现就是为了解决以上问题的。

数据库提供的事务的隔离级别(四种):
1.READ_UNCOMMITED;
允许你读取还未提交的改变了的数据,可能导致脏,幻,不可重复读。
2.READ_COMMINTED:
允许在并发事务已经提交后读取,可防止脏读,但幻读和不可重复读还是有可能发生。
3.REPEATABLE_READ:
对相同字段的多次读取是一致的,除非数据被事务本身改变,可防止脏读,不可重复读,但幻读仍有可能出现。
4.SERILIZABLE:
完全服从ACID的隔离级别,确保不发生脏读,幻读,不可重复读,这在所有的隔离级别中是最慢的,它是典型的完全通过锁定在事务中涉及的数据表来完成的。

除了以上的数据库提供的事务隔离级别,spring提供了Default隔离级别,该级别表示spring使用后端数据库默认的隔离级别。

MySQL默认事务隔离级别:REPATABLE_READ(可能出现幻读)
Oracle默认:READ_COMMITTED(可能出现不可重复读和幻读)

propagation_required:a存在事务,则b与a同一事务,如果a没有事务,则b新起事务
propagation_supported:a存在事务,则b与a同事务,如果a没有事务,则b也没有事务
propagation_mondatary:a存在事务,则b与a同事务,如果a没有事务,则抛异常
propagation_required_new:如果a存在事务,b新起事务
propagation_not_supported:如果a存在事务,b不已事务运行
propagation_never:如果出现事务,直接抛出异常
propagation_nested:a事务运行结束后,会有保存点,这边可以自定事务,b出错,a可以回滚或者就到a的保存点

TransactionDefinition定义事务之事务的传播行为(002)<br>
<br>
事务的传播行为有七种,这七种行为可以分为三类,图中前三个分为一类(让aaa()和bbb()操作在同一事务里),中间三个为一类(保证aaa()和bbb()操作在不同一事务里),最后为一类(aaa()执行完成后,设置一个保存点,如果bbb()发生异常,将回滚到保存点或初始状态)。<br>
<br>
重点记住PROPAGATION_REQUIRED, PROPAGATION_REQUIRES_NEW, PROPAGATION_NESTED

相关代码(公共1):
//package cn.muke.spring.demo1;
@AccountDao.java
/**
* 转账案例的DAO层的接口
*/
public interface AccountDao {
/**
* out :转出账号
* money:转出金额
*/
public void outMoney(String out,Double money);

/**
* in :转入账号
* money:转入金额
*/
public void inMoney(String in,Double money);
}

@AccountService.java
/**
* 转账案例的业务层接口
*/
public interface AccountService {
/**
* out :转出账号
* in :转入账号
* money:转账金额
*/
public void transfer(String out,String in,Double money);
}

@AccountDaoImpl.java
/**
* 转账案例的DAO层的实现类
*/
public class AccountDaoImpl extends JdbcDaoSupport implements AccountDao {
/**
* out :转出账号
* money:转出金额
*/
public void outMoney(String out, Double money) {
String sql="update account set money=money-? where name=?";
this.getJdbcTemplate().update(sql,money,out);
}

/**
* in :转入账号
* money:转入金额
*/
public void inMoney(String in, Double money) {
String sql="update account set money=money+? where name=?";
this.getJdbcTemplate().update(sql,money,in);
}
}
事务的传播行为和隔离级别[transaction behavior and isolated level]
Spring中事务的定义:
一、Propagation :
  key属性确定代理应该给哪个方法增加事务行为。这样的属性最重要的部份是传播行为。有以下选项可供使用:
PROPAGATION_REQUIRED--支持当前事务,如果当前没有事务,就新建一个事务。这是最常见的选择。
PROPAGATION_SUPPORTS--支持当前事务,如果当前没有事务,就以非事务方式执行。
PROPAGATION_MANDATORY--支持当前事务,如果当前没有事务,就抛出异常。
PROPAGATION_REQUIRES_NEW--新建事务,如果当前存在事务,把当前事务挂起。
PROPAGATION_NOT_SUPPORTED--以非事务方式执行操作,如果当前存在事务,就把当前事务挂起。
PROPAGATION_NEVER--以非事务方式执行,如果当前存在事务,则抛出异常。

很多人看到事务的传播行为属性都不甚了解,我昨晚看了j2ee without ejb的时候,看到这里也不了解,甚至重新翻起数据库系统的教材书,但是也没有找到对这个的分析。今天搜索,找到一篇极好的分析文章,虽然这篇文章是重点分析PROPAGATION_REQUIRED 和 PROPAGATION_REQUIRED_NESTED的
解惑 spring 嵌套事务
********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;

*************************************************************************
在这篇文章里,他用两个嵌套的例子辅助分析,我这里直接引用了。
********************sample***********************
ServiceA {

void methodA() {
ServiceB.methodB();
}

}

ServiceB {

void methodB() {
}

}
*************************************************
我们这里一个个分析吧
1: PROPAGATION_REQUIRED
加入当前正要执行的事务不在另外一个事务里,那么就起一个新的事务
比如说,ServiceB.methodB的事务级别定义为PROPAGATION_REQUIRED, 那么由于执行ServiceA.methodA的时候,
ServiceA.methodA已经起了事务,这时调用ServiceB.methodB,ServiceB.methodB看到自己已经运行在ServiceA.methodA
的事务内部,就不再起新的事务。而假如ServiceA.methodA运行的时候发现自己没有在事务中,他就会为自己分配一个事务。
这样,在ServiceA.methodA或者在ServiceB.methodB内的任何地方出现异常,事务都会被回滚。即使ServiceB.methodB的事务已经被
提交,但是ServiceA.methodA在接下来fail要回滚,ServiceB.methodB也要回滚
2: PROPAGATION_SUPPORTS
如果当前在事务中,即以事务的形式运行,如果当前不再一个事务中,那么就以非事务的形式运行
这就跟平常用的普通非事务的代码只有一点点区别了。不理这个,因为我也没有觉得有什么区别
3: PROPAGATION_MANDATORY
必须在一个事务中运行。也就是说,他只能被一个父事务调用。否则,他就要抛出异常。
4: PROPAGATION_REQUIRES_NEW
这个就比较绕口了。 比如我们设计ServiceA.methodA的事务级别为PROPAGATION_REQUIRED,ServiceB.methodB的事务级别为PROPAGATION_REQUIRES_NEW,
那么当执行到ServiceB.methodB的时候,ServiceA.methodA所在的事务就会挂起,ServiceB.methodB会起一个新的事务,等待ServiceB.methodB的事务完成以后,
他才继续执行。他与PROPAGATION_REQUIRED 的事务区别在于事务的回滚程度了。因为ServiceB.methodB是新起一个事务,那么就是存在
两个不同的事务。如果ServiceB.methodB已经提交,那么ServiceA.methodA失败回滚,ServiceB.methodB是不会回滚的。如果ServiceB.methodB失败回滚,
如果他抛出的异常被ServiceA.methodA捕获,ServiceA.methodA事务仍然可能提交。
5: PROPAGATION_NOT_SUPPORTED
当前不支持事务。比如ServiceA.methodA的事务级别是PROPAGATION_REQUIRED ,而ServiceB.methodB的事务级别是PROPAGATION_NOT_SUPPORTED ,
那么当执行到ServiceB.methodB时,ServiceA.methodA的事务挂起,而他以非事务的状态运行完,再继续ServiceA.methodA的事务。
6: PROPAGATION_NEVER
不能在事务中运行。假设ServiceA.methodA的事务级别是PROPAGATION_REQUIRED, 而ServiceB.methodB的事务级别是PROPAGATION_NEVER ,
那么ServiceB.methodB就要抛出异常了。
7: PROPAGATION_NESTED
理解Nested的关键是savepoint。他与PROPAGATION_REQUIRES_NEW的区别是,PROPAGATION_REQUIRES_NEW另起一个事务,将会与他的父事务相互独立,
而Nested的事务和他的父事务是相依的,他的提交是要等和他的父事务一块提交的。也就是说,如果父事务最后回滚,他也要回滚的。
而Nested事务的好处是他有一个savepoint。
*****************************************
ServiceA {

void methodA() {
try {
//savepoint
ServiceB.methodB(); //PROPAGATION_NESTED 级别
} catch (SomeException) {
// 执行其他业务, 如 ServiceC.methodC();
}
}

}
********************************************
也就是说ServiceB.methodB失败回滚,那么ServiceA.methodA也会回滚到savepoint点上,ServiceA.methodA可以选择另外一个分支,比如
ServiceC.methodC,继续执行,来尝试完成自己的事务。
但是这个事务并没有在EJB标准中定义。

二、Isolation Level(事务隔离等级):
1、Serializable:最严格的级别,事务串行执行,资源消耗最大;

2、REPEATABLE READ:保证了一个事务不会修改已经由另一个事务读取但未提交(回滚)的数据。避免了“脏读取”和“不可重复读取”的情况,但是带来了更多的性能损失。

3、READ COMMITTED:大多数主流数据库的默认事务等级,保证了一个事务不会读到另一个并行事务已修改但未提交的数据,避免了“脏读取”。该级别适用于大多数系统。

4、Read Uncommitted:保证了读取过程中不会读取到非法数据。
隔离级别在于处理多事务的并发问题。
我们知道并行可以提高数据库的吞吐量和效率,但是并不是所有的并发事务都可以并发运行,这需要查看数据库教材的可串行化条件判断了。
这里就不阐述。
我们首先说并发中可能发生的3中不讨人喜欢的事情
1: Dirty reads--读脏数据。也就是说,比如事务A的未提交(还依然缓存)的数据被事务B读走,如果事务A失败回滚,会导致事务B所读取的的数据是错误的。

2: non-repeatable reads--数据不可重复读。比如事务A中两处读取数据-total-的值。在第一读的时候,total是100,然后事务B就把total的数据改成200,事务A再读一次,结果就发现,total竟然就变成200了,造成事务A数据混乱。

3: phantom reads--幻象读数据,这个和non-repeatable reads相似,也是同一个事务中多次读不一致的问题。但是non-repeatable reads的不一致是因为他所要取的数据集被改变了(比如total的数据),但是phantom reads所要读的数据的不一致却不是他所要读的数据集改变,而是他的条件数据集改变。比如Select account.id where account.name="ppgogo*",第一次读去了6个符合条件的id,第二次读取的时候,由于事务b把一个帐号的名字由"dd"改成"ppgogo1",结果取出来了7个数据。
Dirty reads non-repeatable reads phantom reads
Serializable 不会 不会 不会
REPEATABLE READ 不会 不会 会
READ COMMITTED 不会 会 会
Read Uncommitted 会 会 会

三、readOnly
事务属性中的readOnly标志表示对应的事务应该被最优化为只读事务。这是一个最优化提示。在一些情况下,一些事务策略能够起到显著的最优化效果,例如在使用Object/Relational映射工具(如:Hibernate或TopLink)时避免dirty checking(试图“刷新”)。
四、Timeout
在事务属性中还有定义“timeout”值的选项,指定事务超时为几秒。在JTA中,这将被简单地传递到J2EE服务器的事务协调程序,并据此得到相应的解释。

事务的API介绍

一、简介
PlatformTransactionManager - 平台事务管理器,真正用来管理事务的接口,包含事务的提交,回滚等信息
TransactionDefinition - 事务定义信息(隔离级别、传播行为、是否超时、设置只读)
TransactionStatus - 事务具体的运行状态(是否已经提交,是否有保存点,是不是一个新的事务等等这些状态)

关系:
首先会根据TransactionDefinition事务定义的信息(比如定义了什么样的隔离级别,定义什么样的传播行为),由PlatformTransactionManager对事务进行管理,进行事务管理的过程中,事务会产生一些相应的状态,这些状态在TransactionStatus中

二、PlatformTransactionManager 接口
1. DataSourceTransactionManager
使用Spring JDBC 或iBatis进行持久化数据时使用
2. HibernateTransactionManager
使用Hibernate3.0版本进行持久化数据时使用

三、TransactionDefinition
1.事务隔离级别
解决脏读、不可重复读、幻读等安全问题

事务隔离级别(四种):
DEFAULT
READ_UNCOMMITED
READ_COMMITED
REPEATABLE_READ
SERIALIZABLE

2.事务的传播行为
解决业务层的方法之间的相互调用的问题(在调用方法的过程中,事务是如何传递的)

事务的传播行为有七种,又分为三类:
第一类共同点:A和B方法在同一个事务中。
*PROPAGATION_REQUIRED
PROPAGATION_SUPPORTS
PROPAGATION_MANDATORY

第二类共同点:A 方法和 B 方法不在同一个事务里面。
*PROPAGATION_REQUIRES_NEW
PROPAGATION_NOT_SUPPORTED
PROPAGATION_NEVER

第三类:如果 A 方法有的事务执行完,设置一个保存点,如果 B 方法中事务执行失败,可以滚回保存点或初始状态。
*PROPAGATION_NESTED

四、TransactionStatus

TransactionStatus接口用来记录事务的状态

该接口定义了一组方法,用来获取或判断事务的相应状态信息.

平台事务管理器(PlatformTransactionManager)会根据TransactionDefinition中定义的事务信息(包括隔离级别、传播行为)来进行事务的管理,在管理的过程中事务可能
产生了保存点或事务是新的事务等情况,那么这些信息都会记录在TransactionStatus的对象中.
TransactionStatus记录事务的状态信息(刷新、是否有保存点、是否完成、是否是一个新事务、是否只回滚、设置只回滚)

SpringAOP和Spring事物管理的更多相关文章

  1. Spring事物管理--相关要点及配置事物管理器

    事务的四大特征 1.原子性:一个事务中所有对数据库的操作是一个不可分割的操作序列,要么全做要么全不做 2.一致性:数据不会因为事务的执行而遭到破坏 3.隔离性:一个事物的执行,不受其他事务的干扰,即并 ...

  2. MyBatis6:MyBatis集成Spring事物管理(下篇)

    前言 前一篇文章<MyBatis5:MyBatis集成Spring事物管理(上篇)>复习了MyBatis的基本使用以及使用Spring管理MyBatis的事物的做法,本文的目的是在这个的基 ...

  3. spring 事物管理没起到作用

    今天在做项目的时候发现配置的spring 事物管理没起到作用.可是配置又是依据官网配置的,不可能会错.最后发现使mysql的问题 普通情况下,mysql会默认提供多种存储引擎,你能够通过以下的查看: ...

  4. java陷阱之spring事物管理导致锁无效

    模拟锁情况无效 1.创建一个表 SET NAMES utf8mb4; ; DROP TABLE IF EXISTS `demo`; CREATE TABLE `demo` ( `id` ) NOT N ...

  5. Spring事物管理简介 (转)

    一.事物1.什么是事物 事物指的是逻辑上的一组操作,这组操作要么全部成功,要么全部失败 2.事物的特性 原子性:事物是一个不可分割的工作单位,事物中的操作要么都发生,要么都不发生 一致性:事物前后数据 ...

  6. 集成Spring事物管理

    什么是事物 事物是访问数据库的一个操作序列,数据库应用系统通过事物集来完成对数据库的存取.事物的正确执行使得数据库从一种状态转换为另一种状态. 事物必须服从ISO/IEC所制定的ACID原则.ACID ...

  7. Spring事物管理机制简单学习

    首先spring并不直接管理事物,而是提供了多种事物管理器,他们将事务管理的职责委托给Hibernate或者JTA等持久化机制所提供的相关平台框架的事务来实现. Spring管理事物的接口是org.s ...

  8. 【JAVA】Spring 事物管理

            在Spring事务管理中通过TransactionProxyFactoryBean配置事务信息,此类通过3个重要接口完成事务的配置及相关操作,分别是PlatformTransactio ...

  9. spring 事物管理

    示例:模拟实现转账操作,"A"转给"B"1000,"A"少1000而"B"多一千. 一.转账环境搭建 1.xml配置文件 ...

随机推荐

  1. Eclipse中Easy Shell插件配置PowerCmd

    1.了解EasyShell.PowerCMD和基本命令 http://sourceforge.net/projects/pluginbox/ http://www.powercmd.com/ 了解基本 ...

  2. ActiveMQ(一) 转

    package pfs.y2017.m11.mq.activemq.demo01; import javax.jms.Connection; import javax.jms.DeliveryMode ...

  3. 未来 5 年八大热门 IT 职业

    近日.外媒梳理了未来5年内.也是就是2020年仍将受到热捧的八大科技领域,为IT从业者怎样做好长远规划.有针对性地培养自身技能.又不偏离热门岗位提供了參考. (图片来自网易) 2020年将热门的8大I ...

  4. 关于Text Kit 一些事

    1. Text Kit 是什么? 在iOS7中,苹果引入了Text Kit--Text Kit是一个高速而又现代化的文字排版和渲染引擎.Text Kit在UIKit framework中的定义了一些类 ...

  5. 嵌入式开发之davinci--- 8168 question about capture PAL on 8168

    http://e2e.ti.com/support/dsp/davinci_digital_media_processors/f/717/t/340483.aspx?pi199607=2

  6. HDU 1032.The 3n + 1 problem【注意细节】【预计数据不强】【8月21】

    The 3n + 1 problem Problem Description Problems in Computer Science are often classified as belongin ...

  7. Codeforces Round #422 (Div. 2) C. Hacker, pack your bags! 排序,贪心

    C. Hacker, pack your bags!     It's well known that the best way to distract from something is to do ...

  8. weblogic 修改控制台console访问路径 url

    出于安全的考虑需要对weblogic的console进行屏避,或者修改默认的访问路径,主要有两种方法:(这里针对weblogic8.1) 一.进入默认的控制台,例如“localhost/console ...

  9. Xamarin.Android 记事本(一)

    导读 1.视图及数据库的创建 2.listview数据绑定 3.listview的点击事件 正文 如何创建一个listview,大家可以看这里,基本流程操作是一模一样的,我就不多说了,然后就是新建一个 ...

  10. VS1053 datasheet 解读笔记

    pdf  10 pdf 11 ` 左右声道 负载,注意这里的负载指LEFT 到GBUF,RIGHT到GBUF.所以后面会有说明GBUF一定不能连接到GND. pdf 14 pdf 14 从上面的引脚定 ...