当地事务系列之四:使用AOP
本地事务系列之四:使用AOP
Spring AOP通过在文件中配置来管理事务,好处是对代码侵入性小。
Spring AOP使用AspectJ表达式来定义切点,所以pom文件加入:
FruitShop实现:
方法中除了使用继承自JdbcDaoSupport的JdbcTemplate来操作数据库外,没有其它与事务有关的代码:
beans-fruitshop-aop.xml文件:
测试类:
Spring AOP通过在文件中配置来管理事务,好处是对代码侵入性小。
Spring AOP使用AspectJ表达式来定义切点,所以pom文件加入:
<dependency> <groupId>org.aspectj</groupId> <artifactId>aspectjweaver</artifactId> <version>1.7.0</version> </dependency>
FruitShop实现:
方法中除了使用继承自JdbcDaoSupport的JdbcTemplate来操作数据库外,没有其它与事务有关的代码:
public class AopTxFruitShop extends JdbcDaoSupport implements FruitShop { @Override public boolean purchase(int fruitId, String userName, int count) { String querySql = "SELECT PRICE FROM FRUIT WHERE ID = ?"; String upStockSql = "UPDATE FRUIT_STOCK SET STOCK = STOCK - ? WHERE ID = ?"; String upAccountSql = "UPDATE ACCOUNT SET BALANCE = BALANCE - ? WHERE USERNAME = ?"; int price = getJdbcTemplate().queryForInt(querySql, new Object[] { fruitId }); getJdbcTemplate().update(upStockSql, new Object[] { count, fruitId }); getJdbcTemplate().update(upAccountSql, new Object[] { price * count, userName }); return true; } }
beans-fruitshop-aop.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:tx="http://www.springframework.org/schema/tx" xmlns:aop="http://www.springframework.org/schema/aop" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd"> <!-- 当transaction-manager属性不指定时,Spring会搜索名称为transactionManager的bean --> <tx:advice id="fruitShopTxAdvice" transaction-manager="txManager"> <tx:attributes><!-- 可以指定多个需要事务的方法 --> <tx:method name="purchase" /><!-- 支持通配符* --> </tx:attributes> </tx:advice> <aop:config> <aop:pointcut id="fruitShopOperation" expression="execution(* com.john.tx.service.impl.AopTxFruitShop.*(..))" /><!-- 切点表达式 --> <aop:advisor advice-ref="fruitShopTxAdvice" pointcut-ref="fruitShopOperation" /> </aop:config> <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource"> <property name="driverClassName" value="com.mysql.jdbc.Driver" /> <property name="url" value="jdbc:mysql://localhost:3306/spring?characterEncoding=utf8" /> <property name="username" value="spring" /> <property name="password" value="123456" /> </bean> <bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <property name="dataSource" ref="dataSource" /> </bean> <bean id="aopTxFruitShop" class="com.john.tx.service.impl.AopTxFruitShop"> <property name="dataSource" ref="dataSource" /> </bean> </beans>
测试类:
@RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(locations = { "classpath:/beans-fruitshop-aop.xml" }) public class AopTxFruitShopTest { @Resource(name = "aopTxFruitShop") FruitShop aopTxFruitShop; @Test public void test() { int fruitId = 1; String userName = "user1"; int count = 3; aopTxFruitShop.purchase(fruitId, userName, count); } }