简介
事务应该在service层启动,但数据库的操作是在dao层.
事务开关的方式
不同的dao层,开启事务的方式不一样,Spring给了不同的事务管理员.
JDBC的事务管理员:DataSourceTransactionManager
- Connection对象.setAutoCommit(false) 获取事务
- Connection对象.commit(); 提交事务
- Connection对象.rollback(); 事务回滚
Hibernate的事务管理员:HibernateTransactionManager
- Session对象.beginTransaction(); 开启事务并返回事务对象
- tx.commit() ;
- tx.rollback() ;
JPA的事务管理员:JpaTransactionManager
- entityManager.beginTransaction();
- tx.commit();
- tx.rollback() ;
事务AOP
声明事务管理员的bean;
- JDBC需要添加 连接池的bean对象
- Hibernate需要添加sessionFactory的bean对象
声明事务的通知
<tx:method>
- name=”方法名”
- read-only=”是否只读” get,list等方法都说只读
- rollback-for=”需要回滚异常” 默认为RuntimeException
- propagation=”事务传播方式”;默认为REQUIRED
- REQUIRED:业务方法如果处于事务中,不再新建事务
- NOT_SUPPORTED:业务方法中,出现DDL语句,本应该提交事务,此时却挂起事务,DDL后在继续事务.
- REQUIRES_NEW:每个业务方法都会新建事务,之前的业务方法被挂起
- 声明切点并织入切面
<!-- 事务管理员 -->
<bean id="txManager" class="HibernateTransactionManager的全限名">
<property name="sessionFactory" ref="sessionFactory"/>
</bean>
<!-- 事务的通知 -->
<tx:advice id="txAdvice" transaction-manager="txManager">
<tx:attributes>
<tx:method name="get*" read-only="true"/>
<tx:method name="list*" read-only="true"/>
<tx:method name="*" propagation="REQUIRED"/>
</tx:attributes>
</tx:advice>
<!-- 织入切面 -->
<aop:config>
<aop:pointcut expression="execution(* *..*DAO*.*(..))" id="pc"/>
<aop:advisor advice-ref="txAdvice" pointcut-ref="pc"/>
</aop:config>