zoukankan      html  css  js  c++  java
  • spring 事务

    自定义注解是动态代理用的

    基本的aop配置

    一个接口DeptService
    实现接口的类DeptServiceImpl,记得加上注解@Service,aop.xml扫描的时候会扫描到
    有那个箭头,表示这些方法都需要切入一些内容


    新建类DeptLog
    方法:

    public void before(){
    System.out.println("DeptLog:before...");
    }
    
    public void afterReturning(){
    System.out.println("DeptLog:afterReturning...");
    }
    
    public void after(){
    System.out.println("DeptLog: after ...");
    }
    
    public Object around(ProceedingJoinPoint jp) throws Throwable{
    System.out.println("DeptLog: around before ...");
    Object o = jp.proceed();// 执行方法
    System.out.println("DeptLog: around after ...");
    
    return o;
    }
    
    public void exception(Exception e){
    System.out.println("DeptLog exception ... "+e.toString());
    }

    新建spring-aop.xml的配置文件,好测试

    <context:component-scan base-package="com.zr"/>    扫描
    <bean id="deptLog" class="com.zr.log.DeptLog"></bean>
    <aop:config>


    设置aop的设置环境,即什么方法需要切入
    <aop:pointcut expression="execution(* com.zr..*(..))" id="deptPointcut"/>扫描
    所有在com.zr下的任意包的任意方法都要被植入新的方法

    <aop:pointcut expression="execution(* com.zr.service..up*(..))" id="updateDeptPointcut"/>扫描
    
    <aop:aspect ref="deptLog">
    <aop:before method="before" pointcut-ref="deptPointcut"/>//表示所有的方法都切入before方法
    <aop:after-returning method="afterReturning" pointcut-ref="deptPointcut"/>
    <aop:after method="after" pointcut-ref="deptPointcut"/>
    <aop:around method="around" pointcut-ref="updateDeptPointcut" />//表示service包下的up开头的方法都切入around方法
    <aop:after-throwing method="exception" pointcut-ref="updateDeptPointcut" throwing="e"/>
    </aop:aspect>
    </aop:config>


    测试的类AopTest
    @Resource(name="deptService")
    private DeptService service;

    @Test
    public void test() {
    service.update();
    }

    20161123
    <url-pattern>*.from</url-pattern>通过from表单提交的东西我这个分发器才做拦截,其他的不做拦截

    AOP注解方式
    aop.xml配置
    <context:component-scan base-package="com.zr.service, com.zr.log"/>
    <aop:aspectj-autoproxy proxy-target-class="true"/>//true cglib的代理方式,jar包的

    新建类DeptLog
    记得加上Bean的注释@Component以及用@Aspect声明这是方面对象

    @Component    //不是控制器、服务层、数据库访问层都使用Component,通用的bean
    @Aspect    //这是一个方面对象
    public class DeptLog {
    @Before("execution(* com.zr.service..save*(..))")//只要符合这个插入规则就在这个范围下的方法下切入方法
    public void before(){
    System.out.println("DeptLog:before...");
    }
    @AfterReturning("execution(* com.zr.service..save*(..))")
    public void afterReturning(){
    System.out.println("DeptLog:afterReturning...");
    }
    @After("execution(* com.zr.service..*(..))")
    public void after(){// 最终通知
    System.out.println("DeptLog: after ...");
    }
    @Around("execution(* com.zr.service..update*(..))")
    public Object around(ProceedingJoinPoint jp) throws Throwable{
    System.out.println("DeptLog: around before ...");
    Object o = jp.proceed();// 执行方法
    System.out.println("DeptLog: around after ...");
    
    return o;
    }
    @AfterThrowing(pointcut="execution(* com.zr.service..*(..))", throwing="e")
    public void afterThrowing(Exception e){
    System.out.println("DeptLog exception ... " + e.toString());
    }
    }


    在类DeptLog的方法上写注解写规则

    测试类AopTest:
    @Resource(name="deptService")
    private DeptService service;

    @Test
    public void test() {
    service.save();
    System.out.println("$$$$$$$$$$$$$$$$$$$$$$$$$$$$$");
    service.update();
    System.out.println("$$$$$$$$$$$$$$$$$$$$$$$$$$$$$");
    service.delete();
    }

    //---------------------------------------------------------------------------------------------------

    事务:
    在spring-db.xml文件增加

    声明事务管理组件
    <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
    <property name="dataSource" ref="dataSource"/>
    </bean>

    配置声明事物的范围及类型
    <tx:advice id="transactionAdvice" transaction-manager="transactionManager">
    <tx:attributes>
    记得添加回滚属性
    <tx:method name="save*" propagation="REQUIRED" isolation="READ_COMMITTED" rollback-for="java.sql.SQLException"/>
    <tx:method name="delete*" propagation="REQUIRED"/>
    <tx:method name="update*" propagation="REQUIRED"/>
    <tx:method name="find*" read-only="true"/>
    </tx:attributes>
    </tx:advice>

    使用AOP配置那些操作需要事务
    <aop:config proxy-target-class="true"> //proxy-target-class="true"使用什么代理,设置为true表示cglp动态代理
    (动态代理用两种,一种JDK自带一种cglp,区别JDK自带的代理对没接口的类不进行代理)
    ***service下的所有方法都添加了上面的事务***
    <aop:advisor advice-ref="transactionAdvice" pointcut="execution(* com.zr.service..*(..))" />//在service包下切入事务
    </aop:config>

    隔离不代表回滚,rollback-for="java.sql.SQLException"当出现sql异常时候回滚

    测试:
    @Resource
    private DeptService service;
    @Test
    public void test() {
    Dept d1 = new Dept();
    d1.setDeptno(90);
    d1.setDname("0901开发班");
    d1.setLoc("车陂");
    service.save(d1);

    d1 = new Dept();
    d1.setDeptno(90);
    d1.setDname("0902开发班");
    d1.setLoc("车陂");
    service.save(d1);
    }
    一次增加两个同样id的,会先把第一个80增加进去,然后数据库就有了,但是下面那个80在执行的时候会抛出异常说明有了
    捕获这个异常,rollback-for="java.sql.SQLException"有了就回滚,两个都增加不进去

    事务注解:db.xml下增加
    <!-- 声明事务管理组件,DataSourceTransactionManager,无论使用注解还是配置XML方式都必须有 -->
    <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
    <property name="dataSource" ref="dataSource"/>
    </bean>

    <!-- 使用注解方式实现事务控制 -->
    <tx:annotation-driven transaction-manager="transactionManager" proxy-target-class="true"/>

    在DeptServiceImpl这个类添加注解@Transactional(isolation=Isolation.READ_COMMITTED, rollbackFor=java.sql.SQLException.class)

    /*
    * 给当前类添加上事务控制
    * @Transactional 可以添加在类上或方法上,如果在类上就是对本类的所有方法实现同样事务处理方式
    * 如果是在方法,只针对添加注解的方法
    */

  • 相关阅读:
    医疗设备软件的安全性问答
    python使用技巧
    C++对象模型
    面向对象方法综述
    如何设计可扩展性系统架构
    敏捷过程
    python中import的相关知识总结
    软件架构的关键原则
    读后感——程序员的思维修炼
    LINUX系统备份工具
  • 原文地址:https://www.cnblogs.com/qingyibusi/p/6591060.html
Copyright © 2011-2022 走看看