一、什麼叫做聲明式事務?
對應編程式事務:
每次對數據庫操作時,都通過java語句去控制,比如以Hibernate爲例,對事務的管理即是在try…catch中開啓,提交,回滾操作:
try {
session.beginTransaction();
....
session.getTransaction.commit();
}catch(Exception e) {
}finally {
session.getTransaction.rollback();
}
但是當我們項目需要管理很多事務的時候,就會出現相同代碼不斷重複,事務管理煩瑣等等問題,而聲明式事務可以通過xml或者註解的形式,對需要加入事務的方法進行聲明即可,將事務統一管理起來,也讓我們更專注於代碼邏輯,提高開發的效率。
spring的事務實現,由org.springframework.transaction.PlatformTransactionManager接口去實現,此接口是事務管理的核心,提供了三個需要實現的函數:
commit(TransactionStatus status) ;
getTransaction(TransactionDefinition definition) ;
rollback(TransactionStatus status) ;
不管用編程式還是聲明式,都有這三個接口去實現。
編程式暫且不論,因爲我們要使用spring事務管理就是使用它的聲明式事務。
二、spring提供兩種事務管理方式
1.xml配置(aop技術)
<!-- 定義事務處理類,不同的數據訪問方式,事務處理類不同
比如:Hibernate操作的HibernateTransactionManager,JDBC操作的使用DataSourceTransactionManager
-->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"></property>
</bean>
<!-- 定義事務通知 -->
<tx:advice id="txAdvice" transaction-manager="transactionManager">
<!-- 定義方法的過濾規則 -->
<tx:attributes>
<!-- 所有方法都使用事務 -->
<tx:method name="*" propagation="REQUIRED"/>
<!-- 定義所有get開頭的方法都是隻讀的 -->
<tx:method name="get*" read-only="true"/>
</tx:attributes>
</tx:advice>
<!-- 定義AOP配置 -->
<aop:config>
<!-- 定義一個切入點 -->
<aop:pointcut expression="execution (* com.iflysse.school.services.impl.*.*(..))" id="services"/>
<!-- 對切入點和事務的通知,進行適配 -->
<aop:advisor advice-ref="txAdvice" pointcut-ref="services"/>
</aop:config>
2.annotation(註解)
只需要在Spring配置文件中定義一個事務管理對象(如DataSourceTransactionManager),然後加入<tx:annotation-driven/>節點,引用該事務管理對象,然後即可在需要進行事務處理的類和方法使用@Transactional進行標註。
<!-- 定義事務處理類,不同的數據訪問方式,事務處理類不同
比如:Hibernate操作的HibernateTransactionManager,JDBC操作的使用DataSourceTransactionManager
-->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"></property>
</bean>
<!-- 聲明使用註解式事務 -->
<tx:annotation-driven transaction-manager="transactionManager"/>
@Service
@Transactional(propagation = Propagation.REQUIRED)
public class TeacherServicesImpl implements TeacherServices {
@Autowired
TeacherDao dao = null;
public TeacherDao getDao() {
return dao;
}
public void setDao(TeacherDao dao) {
this.dao = dao;
}
@Override
@Transactional(readOnly=true,propagation=Propagation.NEVER)
public List<Teacher> getAllTeachers() {
return getDao().getAllTeachers();
}
@Override
public void addTeacher(Teacher teacher) {
if(teacher.getId() > 0){
getDao().updateTeacher(teacher);
}else{
getDao().addTeacher(teacher);
}
}
}
三、總結
兩種方式各有特點,就像是ORM既可以通過XML也可以用註解實現一樣,各有特點。XML集中管理,和java代碼相分離,修改更新上更靈活,並且相比註解的形式能實現的功能更強;註解的方式對比xml編寫簡單明瞭,相比xml是類型安全的,編譯時就能發現問題;兩種方式沒有優劣,其實只要能解決我們的問題,讓問題簡單化就可以。