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 可以添加在类上或方法上,如果在类上就是对本类的所有方法实现同样事务处理方式
* 如果是在方法,只针对添加注解的方法
*/

原文地址:https://www.cnblogs.com/qingyibusi/p/6591060.html