多数的情况。假设 ServiveX#methodX() 都工作在事务环境下(即都被 Spring 事务增强了),假设程序中存在如 下的调用链:Service1#method1()->Service2#method2()->Service3#method3(),那么 这 3 个服务类的 3 个方法通过 Spring 的事务传播机制都工作在同一个事务中。
下面,我们来看一下实例,UserService#logon() 方法内部调用了 UserService#updateLastLogonTime() 和 ScoreService#addScore() 方法,这两个类都继承于 BaseService。它们之间的类结构说明如下:
图 1. UserService 和 ScoreService
Spring事务管理高级应用难点剖析,第1部分(9)
时间:2012-04-26 IBM 陈雄华
具体的代码如下所示:
清单 9 UserService.java
@Service("userService")
public class UserService extends BaseService {
@Autowired
private JdbcTemplate jdbcTemplate;
@Autowired
private ScoreService scoreService;
public void logon(String userName) {
updateLastLogonTime(userName);
scoreService.addScore(userName, 20);
}
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 的代码如下所示:
清单 10 ScoreService.java
@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 中所有公有方法都添加事务增 强,让这些方法都工作于事务环境下。下面是关键的配置代码:
清单 11 事务增强配置
<!-- 添加Spring事务增强 -->
<aop:config proxy-target-class="true">
<aop:pointcut id="serviceJdbcMethod"
<!-- 所有继承于BaseService类的子孙类的public方法都进行事务增强-->
expression="within(user.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>
Spring事务管理高级应用难点剖析,第1部分(10)
时间:2012-04-26 IBM 陈雄华
将日志级别设置为 DEBUG,启动 Spring 容器并执行 UserService#logon() 的方法,仔细 观察如下的输出日志:
清单 12 执行日志
16:25:04,765 DEBUG (AbstractPlatformTransactionManager.java:365) -
Creating new transaction with name [user.nestcall.UserService.logon]:
PROPAGATION_REQUIRED,ISOLATION_DEFAULT ①为UserService#logon方法启动一个事务
16:25:04,765 DEBUG (DataSourceTransactionManager.ja
|