采用
基于XML
方式配置事务
<bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <property name="dataSource" ref="dataSource"/> </bean> <aop:config> <aop:pointcut id="transactionPointcut" expression="execution(* cn.itcast.service..*.*(..))"/> <aop:advisor advice-ref="txAdvice" pointcut-ref="transactionPointcut"/> </aop:config> <tx:advice id="txAdvice" transaction-manager="txManager"> <tx:attributes> <tx:method name="get*" read-only="true" propagation="NOT_SUPPORTED"/> <tx:method name="*"/> </tx:attributes> </tx:advice>
例子:我们使用xml配置的方式实现事务控制
步骤:1 .先写接口,再写实现,实现中去掉注解
package cn.com.xinli.service.impl;
import java.util.List;
import javax.sql.DataSource;
import org.springframework.jdbc.core.JdbcTemplate;
import cn.com.xinli.bean.Person;
import cn.com.xinli.service.PersonService;
public class PersonServiceBean implements PersonService
{
public JdbcTemplate jdbcTemplate;
public DataSource dataSource;
public DataSource getDataSource()
{
return dataSource;
}
public void setDataSource(DataSource dataSource) {
this.jdbcTemplate = new JdbcTemplate(dataSource);
}
public void delete(Integer personid) {
jdbcTemplate.update("delete from person where id=?", new Object[]{personid},
new int[]{java.sql.Types.INTEGER});
}
public Person getPerson(Integer personid) {
return (Person)jdbcTemplate.queryForObject("select * from person where id=?", new Object[]{personid},
new int[]{java.sql.Types.INTEGER}, new PersonRowMapper());
}
@SuppressWarnings("unchecked")
public List<Person> getPersons() {
return (List<Person>)jdbcTemplate.query("select * from person", new PersonRowMapper());
}
public void save(Person person) {
jdbcTemplate.update("insert into person(name) values(?)", new Object[]{person.getName()},
new int[]{java.sql.Types.VARCHAR});
}
public void update(Person person) {
jdbcTemplate.update("update person set name=? where id=?", new Object[]{person.getName(), person.getId()},
new int[]{java.sql.Types.VARCHAR, java.sql.Types.INTEGER});
}
}
2.在beans.xml 中配置事务,也就是配置一个aop
<!-- 配置事务-->
<bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"/>
</bean>
<!-- 配置事务管理器 (基于注解的事务需要此配置,基于xml配置事务应该去掉此配置)
<tx:annotation-driven transaction-manager="txManager"/>
-->
<bean id="personService" class="cn.com.xinli.service.impl.PersonServiceBean">
<property name="dataSource" ref="dataSource"></property>
</bean>
<aop:config>
<!-- 配置一个切面,和需要拦截的类和方法 -->
<aop:pointcut id="transactionPointcut" expression="execution(* cn.com.xinli.service..*.*(..))"/>
<!-- 引用一个事务通知 -->
<aop:advisor advice-ref="txAdvice" pointcut-ref="transactionPointcut"/>
</aop:config>
<!-- 配置一个事务通知 -->
<tx:advice id="txAdvice" transaction-manager="txManager">
<tx:attributes>
<tx:method name="get*" read-only="true" propagation="NOT_SUPPORTED"/>
<tx:method name="*"/>
</tx:attributes>
</tx:advice>
3.在delete 方法中抛出一个 运行期例外 ,如果事务起作用,那么要删除的记录汇回滚。
public void delete(Integer personid) {
jdbcTemplate.update("delete from person where id=?", new Object[]{personid},
new int[]{java.sql.Types.INTEGER});
throw new RuntimeException("我是例外");
}
4.测试
public void testDelete() throws Exception{
personService.delete(5);
}
5结果
由于配置了事务,在业务方法中有 运行期例外,则事务回滚,并没有删除id 为5的记录,
在bean.xml中去掉事务的配置,在运行测试用例,发现id为5的记录已经被删除,可见xml配置事务起了作用,是要也是利用了aop,在拦截到方法的时候为方法加上事务