UserService#logon()方法內部調用了ScoreService#addScore()的方法,二者都分別經過Spring AOP進行了事務加強,則它們工做於同一事務中。來看具體的代碼: java
package com.baobaotao.nestcall; … @Service("userService") public class UserService extends BaseService { @Autowired private JdbcTemplate jdbcTemplate; @Autowired private ScoreService scoreService; //①該方法嵌套調用了本類的其餘方法及其餘服務類的方法 public void logon(String userName) { System.out.println("before userService.updateLastLogonTime..."); updateLastLogonTime(userName);//①-1本服務類的其餘方法 System.out.println("after userService.updateLastLogonTime..."); System.out.println("before scoreService.addScore..."); scoreService.addScore(userName, 20); //①-2其餘服務類的其餘方法 System.out.println("after scoreService.addScore..."); } public void updateLastLogonTime(String userName) { String sql = "UPDATE t_user u SET u.last_logon_time = ? WHERE user_name =?"; jdbcTemplate.update(sql, System.currentTimeMillis(), userName); }
UserService中注入了ScoreService的Bean,而ScoreService的代碼以下所示: mysql
package com.baobaotao.nestcall; … @Service("scoreUserService") public class ScoreService extends BaseService{ @Autowired private JdbcTemplate jdbcTemplate; public void addScore(String userName, int toAdd) { String sql = "UPDATE t_user u SET u.score = u.score + ? WHERE user_name =?"; jdbcTemplate.update(sql, toAdd, userName); } }
經過Spring配置爲ScoreService及UserService中全部公有方法都添加Spring AOP的事務加強,讓UserService的logon()和updateLastLogonTime()及ScoreService的 addScore()方法都工做於事務環境下。下面是關鍵的配置代碼: spring
<?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:p="http://www.springframework.org/schema/p" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd"> <context:component-scan base-package="com.baobaotao.nestcall"/> … <bean id="jdbcManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager" p:dataSource-ref="dataSource"/> <!--①經過如下配置爲全部繼承BaseService類的全部子類的全部public方法都添加事務加強--> <aop:config proxy-target-class="true"> <aop:pointcut id="serviceJdbcMethod" expression="within(com.baobaotao.nestcall.BaseService+)"/> <aop:advisor pointcut-ref="serviceJdbcMethod" advice-ref="jdbcAdvice" order="0"/> </aop:config> <tx:advice id="jdbcAdvice" transaction-manager="jdbcManager"> <tx:attributes> <tx:method name="*"/> </tx:attributes> </tx:advice> </beans>
將日誌級別設置爲DEBUG,啓動Spring容器並執行UserService#logon()的方法,仔細觀察以下輸出日誌:sql