表结构
目录结构
1.基于xml的声明式事务,如下(applicationContext.xml)
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xmlns:tx="http://www.springframework.org/schema/tx" xmlns:aop="http://www.springframework.org/schema/aop" xsi:schemaLocation=" http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> <!-- 组件扫描 --> <context:component-scan base-package="com.alibaba.dao.impl"></context:component-scan> <!-- 加载jdbc,properties --> <context:property-placeholder location="classpath:jdbc.properties"/> <!-- 配置数据源 --> <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"> <property name="driverClass" value="${jdbc.driver}"></property> <property name="jdbcUrl" value="${jdbc.url}"></property> <property name="user" value="${jdbc.username}"></property> <property name="password" value="${jdbc.password}"></property> </bean> <!-- 配置Jdbc模板对象 --> <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate"> <property name="dataSource" ref="dataSource"/> </bean> <!-- 配置Dao对象 --> <bean id="accountDao" class="com.alibaba.dao.impl.AccountDaoImpl"> <property name="jdbcTemplate" ref="jdbcTemplate"></property> </bean> <!-- 配置service对象 --> <bean id="accountService" class="com.alibaba.service.impl.AccountServiceImpl"> <property name="accountDao" ref="accountDao"></property> </bean> <!-- 配置平台事务管理器 --> <bean id="transcationManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <property name="dataSource" ref="dataSource"/> </bean> <!-- 配置事务的Aop切面 --> <aop:config> <aop:advisor advice-ref="txAdvice" pointcut="execution(* com.alibaba.service.impl.*.*(..))"/> </aop:config> <!-- 配置事务增强 --> <tx:advice id="txAdvice" transaction-manager="transcationManager"> <!-- 事务属性配置--> <tx:attributes> <!-- name:方法名称 *代表全部 isolation:隔离级别 propagation:传播行为 read-only: 是否只读 --> <tx:method name="*" isolation="REPEATABLE_READ" propagation="REQUIRED" read-only="false"/> <tx:method name="findAll" read-only="true"/> <tx:method name="find*" read-only="true"/> </tx:attributes> </tx:advice> </beans>
2.半注解配置
1).applicationContext.xml
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xmlns:tx="http://www.springframework.org/schema/tx" xmlns:aop="http://www.springframework.org/schema/aop" xsi:schemaLocation=" http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> <!-- 加载jdbc.properties文件 --> <context:property-placeholder location="classpath:jdbc.properties"/> <!-- 配置数据源 --> <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"> <property name="driverClass" value="${jdbc.driver}"></property> <property name="jdbcUrl" value="${jdbc.url}"></property> <property name="user" value="${jdbc.username}"></property> <property name="password" value="${jdbc.password}"></property> </bean> <!-- 配置jdbc模版对象 --> <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate"> <property name="dataSource" ref="dataSource"></property> </bean> <!-- 配置平台事务管理器 --> <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <property name="dataSource" ref="dataSource"></property> </bean> <!-- 组件扫描 --> <context:component-scan base-package="com.alibaba"></context:component-scan> <!-- 事务的注解驱动 --> <tx:annotation-driven transaction-manager="transactionManager"/> </beans>
2).service层的配置
@Service("accountService") /* @Transactional 可以作用于接口、接口方法、类以及类方法上。当作用于类上时,该类的所有 public 方法将都具有该类型的事务属性, 同时,我们也可以在方法级别使用该标注来覆盖类级别的定义。虽然 @Transactional 注解可以作用于接口、接口方法、类以及类方法上, 但是 Spring 建议不要在接口或者接口方法上使用该注解,因为这只有在使用基于接口的代理时它才会生效。另外, @Transactional 注解应该只被应用到 public 方法上,这是由 Spring AOP 的本质决定的。如果你在 protected、private 或者默认可见性的方法上 使用 @Transactional 注解,这将被忽略,也不会抛出任何异常。默认情况下,只有来自外部的方法调用才会被AOP代理捕获,也就是 类内部方法调用本类内部的其他方法并不会引起事务行为,即使被调用方法使用@Transactional注解进行修饰。 */ @Transactional public class AccountServiceImpl implements AccountService { @Autowired private AccountDao accountDao; @Override // @Transactional(isolation = Isolation.DEFAULT, propagation=Propagation.REQUIRED, readOnly = false) public void transfer(String outMan, String inMan, Double money) { int i = 1 / 0; //转出钱 accountDao.out(outMan, money); //转入钱 accountDao.in(inMan, money); } }
3.全注解配置
1).applicationContext.xml
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xmlns:tx="http://www.springframework.org/schema/tx" xmlns:aop="http://www.springframework.org/schema/aop" xsi:schemaLocation=" http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> <!-- 加载jdbc.properties文件 --> <context:property-placeholder location="classpath:jdbc.properties"/> <!-- 配置数据源 --> <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"> <property name="driverClass" value="${jdbc.driver}"></property> <property name="jdbcUrl" value="${jdbc.url}"></property> <property name="user" value="${jdbc.username}"></property> <property name="password" value="${jdbc.password}"></property> </bean> <!-- 配置jdbc模版对象 --> <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate"> <property name="dataSource" ref="dataSource"></property> </bean> <!-- 配置平台事务管理器 --> <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <property name="dataSource" ref="dataSource"></property> </bean> <!-- 组件扫描 --> <context:component-scan base-package="com.alibaba"></context:component-scan> <!-- 事务的注解驱动 --> <tx:annotation-driven transaction-manager="transactionManager"/> </beans>
3).添加配置事务类
@Configuration //<context:component-scan base-package="com.alibaba"></context:component-scan> @ComponentScan("com.alibaba") //<tx:annotation-driven transaction-manager="transactionManager"/> @EnableTransactionManagement public class SpringConfiguration { @Bean(name="dataSource") public DataSource getDataSource() throws PropertyVetoException{ ComboPooledDataSource dataSource = new ComboPooledDataSource(); dataSource.setDriverClass("com.mysql.jdbc.Driver"); dataSource.setJdbcUrl("jdbc:mysql:///testBase"); dataSource.setUser("root"); dataSource.setPassword("root"); return dataSource; } @Bean(name="jdbcTemplate") public JdbcTemplate getJdbcTemplate(@Qualifier("dataSource") DataSource dataSource) { JdbcTemplate jdbcTemplate = new JdbcTemplate(); jdbcTemplate.setDataSource(dataSource); return jdbcTemplate; } @Bean(name="transactionManager") public DataSourceTransactionManager getDataSourceTransactionManager(@Qualifier("dataSource") DataSource dataSource) { DataSourceTransactionManager transactionManager = new DataSourceTransactionManager(); transactionManager.setDataSource(dataSource); return transactionManager; } }
3).测试类
@Test //测试转账的效果(全注解方式) public void test(){ ApplicationContext app = new AnnotationConfigApplicationContext(SpringConfiguration.class); AccountService accountService = (AccountService) app.getBean("accountService"); accountService.transfer("jack", "tom", 500); }