spring 事務

不知為何就叫呵呵發表於2017-03-20

自定義註解是動態代理用的

基本的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 可以新增在類上或方法上,如果在類上就是對本類的所有方法實現同樣事務處理方式
* 如果是在方法,只針對新增註解的方法
*/

 

相關文章