一、什么叫做声明式事务?
对应编程式事务:
每次对数据库操作时,都通过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是类型安全的,编译时就能发现问题;两种方式没有优劣,其实只要能解决我们的问题,让问题简单化就可以。