举例a向b转账,通过money总量来查看在转账出现异常时数据能否保持一致性。
主体结构 | jar包 |
db.properties:
jdbc.jdbcUrl=jdbc:mysql:///spring_day03 jdbc.driverClass=com.mysql.jdbc.Driver jdbc.user=root jdbc.password=root
applicationContext.xml:
1 <?xml version="1.0" encoding="UTF-8"?> 2 <beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 3 xmlns:aop="http://www.springframework.org/schema/aop" 4 xmlns="http://www.springframework.org/schema/beans" 5 xmlns:context="http://www.springframework.org/schema/context" 6 xmlns:tx="http://www.springframework.org/schema/tx" 7 xsi:schemaLocation="http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.2.xsd http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.2.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.2.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.2.xsd "> 8 <context:property-placeholder location="db.properties"/> 9 10 <!-- 配置DataSource --> 11 <bean name="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"> 12 <property name="jdbcUrl" value="${jdbc.jdbcUrl}"></property> 13 <property name="driverClass" value="${jdbc.driverClass}"></property> 14 <property name="user" value="${jdbc.user}"></property> 15 <property name="password" value="${jdbc.password}"></property> 16 </bean> 17 18 <!-- 配置TransactionManager --> 19 <bean name="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> 20 <property name="dataSource" ref="dataSource"></property> 21 </bean> 22 23 <!-- 配置AccountDao --> 24 <bean name="accountDao" class="com.kong.dao.AccountDaoImpl"> 25 <property name="dataSource" ref="dataSource"></property> 26 </bean> 27 28 <!-- 配置AccountService --> 29 <bean name="accountService" class="com.kong.service.AccountServiceImpl"> 30 <property name="accountDao" ref="accountDao"></property> 31 </bean> 32 33 <!-- 配置Transaction通知 --> 34 <tx:advice transaction-manager="transactionManager" id="myAdvice"> 35 <tx:attributes> 36 <tx:method name="transfer" isolation="REPEATABLE_READ" propagation="REQUIRED" read-only="false"/> 37 </tx:attributes> 38 </tx:advice> 39 40 <!-- transaction、aspect织入 --> 41 <aop:config> 42 <aop:pointcut expression="execution(* com.kong.service.*ServiceImpl.*(..))" id="myPointCut"/> 43 <aop:advisor advice-ref="myAdvice" pointcut-ref="myPointCut"/> 44 </aop:config> 45 46 47 48 </beans>
AccountDaoImpl.java:
package com.kong.dao; import org.springframework.jdbc.core.support.JdbcDaoSupport; public class AccountDaoImpl extends JdbcDaoSupport implements AccountDao { @Override public void addMoney(Integer id, double money) { String sql = "update t_account set money = money + ? where id = ?"; super.getJdbcTemplate().update(sql,money,id); } @Override public void subMoney(Integer id, double money) { String sql = "update t_account set money = money - ? where id = ?"; super.getJdbcTemplate().update(sql,money,id); } }
AccountServiceImpl.java:
package com.kong.service; import com.kong.dao.AccountDao; public class AccountServiceImpl implements AccountService { private AccountDao accountDao; public void setAccountDao(AccountDao accountDao) { this.accountDao = accountDao; } @Override public void transfer(Integer from, Integer to, double money) { accountDao.subMoney(from, money); System.out.println(1/0);//插入出错代码 accountDao.addMoney(to, money); } }
Mytest.java:
package com.kong.test; import javax.annotation.Resource; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; import com.kong.service.AccountService; @RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration("classpath:applicationContext.xml") public class MyTest { @Resource(name = "accountService") private AccountService accountService; @Test //id=1向id=2转账100 public void test_01() { accountService.transfer(1, 2, 100d); } }
原表数据:
若未配置织入(line 41~44@applicationContext.xml),则在出现异常时运行结果为:
若配置了织入,则在出现异常时程序的运行结果为:
在引入spring 事务管理后,可以保持数据的一致性