在Spring中的事务中,xml的配置方式很重要,因为它可以通过一些特殊表达式仅仅是简单设置就可以为所有或者部分业务层的方法加上事务控制。这在业务层逻辑十分复杂,或者业务层方法十分多的时候无意是十分方便的。
下面就将前面的事物配置转到XML中进行配置。首先,删除掉前面的事物控制的annotation。代码如下:
@Service("userService")
public class UserService {
private UserDAO userDAO;
private MsgDAO msgDao;
//@Transactional(propagation=Propagation.REQUIRED,readOnly=false)
public void add(User user) {
userDAO.save(user);
Msg msg = new Msg();
msg.setLog("a user saved!");
msgDao.save(msg);
}
public UserDAO getUserDAO() {
return userDAO;
}
@Resource(name="userDao")
public void setUserDAO(UserDAO userDAO) {
this.userDAO = userDAO;
}
public MsgDAO getMsgDao() {
return msgDao;
}
@Resource(name="msgDao")
public void setMsgDao(MsgDAO msgDao) {
this.msgDao = msgDao;
}
}
然后,修改beans.xml中的最后部分:
<bean id="transactionManager"
class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory"></property>
</bean>
<!-- 定义一个切面,规定使用的事务建议 -->
<aop:config>
<aop:pointcut id="business" expression="execution(public * com.zxb.service..*.add(..))"/>
<aop:advisor pointcut-ref="business" advice-ref="txAdvice"/>
</aop:config>
<!-- 定义事务建议 -->
<tx:advice id="txAdvice" transaction-manager="transactionManager">
<tx:attributes>
<!-- 定义事务属性 -->
<tx:method name="add" propagation="REQUIRED" read-only="false"/>
<tx:method name="get*" propagation="REQUIRED" read-only="true"/>
</tx:attributes>
</tx:advice>
<!-- 删除这句,事务控制在XML文件中完成。
<tx:annotation-driven transaction-manager="transactionManager"/>
-->
经过测试,事务控制正常。
一个小的知识点:我们插入User的以后,在插入Msg的时候,如果在一个事物里,如果在插入Msg失败了,Msg表中的记录是直接回滚,下次插入的时候,ID还是连续的,但是同一个事务回滚的时候User则是采用的删除方式,下次成功插入数据的时候,ID是不连续的,会跳过插入失败那一次的ID值。