spring(七)AOP,事务的隔离级别、传播特性、配置

来源:互联网 发布:sql select as语句 编辑:程序博客网 时间:2024/06/08 07:30

AOP概念

Aop即面向切面编程、面向核心的业务方法编程,非核心交给spring去做,在模块中占的比重非常少,主要体现是用在事务管理上。
1. 切面(Aspect):面向切面的“面”就是指的是本类,在类中面的组成就是方法的集合,JAVABean对应切面。
2. 连接点(JoinPoint)程序运行过程中的某个阶段点。如某个方法调用,或者某个异常被抛出。
3. 通知(Advice):处理逻辑,方法体中的业务逻辑,某个方法里面的具体逻辑。
4. 切点(PointCut)一系列连接点的集合,它指明处理方式(Advice)将在何时被触发,就是方法的集合。
结论:程序员只是关注最主要的业务逻辑或者方法。

为什么需要AOP

面向切面编程能使程序员只是关注最主要的业务逻辑或者方法,其余与业务无关的方法交个第三方面来做,腾出大量的时间使程序员关注最核心的业务方法,节省时间提高开发效率,是spring在面向对象的思想上新提出的一种编程思想。

事务的隔离级别

Isolation.READ_UNCOMMITTED:读取未提交数据(会脏读和不可重复读)基本不用。
Isolation.READ_COMMITTED:读已提交数据(不可重复读和幻读)oracle数据库默认。
Isolation.REPETABLE_READ:可重复读(幻读)。Mysql和SQL server默认。
Isolation_SERIALIZABLE:串行化,最严格的级别,事务串行执行,资源消耗最大。
脏读:一个事务读取到另一个事务的未提交的数据,包含已提交的和未提交的,另一个事务回滚后数据又不见了。也就是说,比如事务A的未提交(还依然缓存)的数据被事务B读走,如果事务A失败回滚,会导致事务B所读取的的数据是错误的。
不可重复读:在同一事务中多次读取同一数据返回的结果有所不同,你在读的时候其它人在修改。比如事务A中两处读取数据-total-的值。在第一读的时候,total是100,然后事务B就把total的数据改成 200,事务A再读一次,结果就发现,total竟然就变成200了,造成事务A数据混乱。相反,可重复多次读取数据时能够保证读取数据一样,也就是后续读取不能读取另一个事务已提交的更新数据。
幻读:一个事务读到另一个事务已提交的insert数据。这个和不可重复读相似,也是同一个事务中多次读不一致的问题。但是不可重复读的不一致是因为他所要取的数据集被改变了(比如total的数据),但是幻读所要读的数据的不一致却不是他所要读的数据集改变,而是他的条件数据集改变。比如Select account.id where account.name=”ppgogo*”,第一次读去了6个符合条件的id,第二次读取的时候,由于事务b把一个帐号的名字由”dd”改成”ppgogo1”,结果取出来了7个数据。

事务传播特性

在spring中基本的六种事务传播(事务常量):
1. PROPAGATION_REQUIRED: 如果存在一个事务,则支持当前事务。如果没有事务则开启。
2. PROPAGATION_SUPPORTS: 如果存在一个事务,支持当前事务。如果没有事务,则非事务的执行。
3. PROPAGATION_MANDATORY: 如果已经存在一个事务,支持当前事务。如果没有一个活动的事务,则抛出异常。
4. PROPAGATION_REQUIRES_NEW: 总是开启一个新的事务。如果一个事务已经存在,则将这个存在的事务挂起。
5. PROPAGATION_NOT_SUPPORTED: 总是非事务地执行,并挂起任何存在的事务。
6. PROPAGATION_NEVER: 总是非事务地执行,如果存在一个活动事务,则抛出异常。

spring配置事务

不配置也可进行操作,因为默认情况下是自动的处理事务,也可以手动配置。该配置是在ssm的基础上进行的。

jar包

在SSMjar包的基础上添加:spring-aop和spring-aspects的依赖,依赖包需要去2.0的spring源码包中找,其中aop的依赖是applicance,aspects的依赖是aspectjrt和aspectjweaver.

配置文件

1.在配置文件的头部添加tx和aop的头

<?xml version="1.0" encoding="UTF-8"?><beans xmlns="http://www.springframework.org/schema/beans"    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop"    xmlns:tx="http://www.springframework.org/schema/tx"    xsi:schemaLocation="  http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd  http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd  http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd">

2.配事务管理者

    <!-- 集成mybatis提供的事务管理者 -->    <bean id="transactionManager"    class="org.springframework.jdbc.datasource.DataSourceTransactionManager">        <property name="dataSource" ref="mydataSource" />    </bean>

3.配事务管理属性

name:代表名称符合该属性的值的方法有该事务。
isolation:某个方法的事务隔离级别。
propagation:事务的传播方式
rollback-for:有异常回滚值为异常类,前面加no代表有异常不回滚。
time-out:事务的过期时间,-1是永不过期,配30表示30毫秒不动就过期

<tx:advice id="txAdvice" transaction-manager="transactionManager">        <tx:attributes>            <tx:method name="delete*" propagation="REQUIRED"                rollback-for="java.lang.Exception" />            <tx:method name="save*" propagation="REQUIRED"                rollback-for="java.lang.Exception" />            <tx:method name="update*" propagation="REQUIRED"                rollback-for="java.lang.Exception" />            <tx:method name="find*" isolation="READ_COMMITTED"                read-only="true" />            <tx:method name="*" isolation="READ_COMMITTED" propagation="REQUIRED"                read-only="true" />        </tx:attributes>    </tx:advice>

4.谁配置这个事务,将其配置到业务逻辑层。

aop:pointcut把事务的属性注入到
advisor:通知
execution(* com.sxt.service..(..)):该表达式一般是固定的,第一个.表示这个包下的所有类,第二个.表示类中的所有方法,(..)表示方法的参数

    <aop:config>        <aop:pointcut id="pc" expression="execution(* com.sxt.service.*.*(..))" />        <aop:advisor advice-ref="txAdvice" pointcut-ref="pc" />    </aop:config>

注解方式

在业务逻辑层配。在类的头部或者方法的头部添加@Transactional注解,类头配表示这是全局事务对这个类底下的所有方法有效,
只能写在public修饰的方法上,也可以在接口上写,写时是一样的,但官方文档建议在类上写,一般情况下增删改在类上写,查询单独配,当类头部和方法的头部都配置时,事务运用就近原则。
注解中的属性,和配置文件方式的配置是相同的,rollbackFor:既可以配置一个,也可以配多个异常。

package com.sxt.service;import java.sql.SQLException;import java.util.List;import javax.annotation.Resource;import org.springframework.stereotype.Service;import org.springframework.transaction.annotation.Isolation;import org.springframework.transaction.annotation.Propagation;import org.springframework.transaction.annotation.Transactional;import com.sxt.dao.DeptDaoMapper;import com.sxt.entity.Dept;@Service@Transactional(propagation=Propagation.REQUIRED,rollbackFor={SQLException.class,Exception.class})public class DeptService {    @Resource(name="deptDaoMapper")    private DeptDaoMapper deptDaoMapper;    @Transactional(isolation=Isolation.READ_COMMITTED,readOnly=true,propagation=Propagation.REQUIRED)    public List<Dept>findDept(){        return deptDaoMapper.findDept();    }    @Transactional(propagation=Propagation.REQUIRED,rollbackFor={SQLException.class,Exception.class})    public void save(){    }    @Transactional(propagation=Propagation.REQUIRED,rollbackForClassName={"SQLException","Exception"})    public void delete(){    }    @Transactional(propagation=Propagation.REQUIRED,rollbackForClassName={"SQLException","Exception"})    public void update(){    }}
阅读全文
0 0