您的位置:首页 > 编程语言 > Java开发

说说在 Spring 中,如何基于 XML 来配置事务

2019-04-14 15:03 357 查看
版权声明:如果喜欢,就点个赞呗 O(∩_∩)O~ https://blog.csdn.net/deniro_li/article/details/89296586

我们大都选择使用声明式(XML 或者注解)来配置事务,因为这种方式对代码的侵入最小。特别是 XML 方式的配置,可以让事务管理配置信息从业务代码中完全移除。

Spring 的声明式事务管理是通过 AOP 实现的。 Spring 会读取事务的声明配置,将事务管理的增强逻辑,动态织入到业务方法的相应连接点中 。

Spring 2.0 之后引入了 AspectJ 切面定义语言,所以我们可以基于 aop/tx 命名空间来配置事务。

假设有这样的一个 UserService 类:

@Service
public class UserService {

@Autowired
private UserDao userDao;

/**
* 新增
*
* @param user
*/
public int addUser(final User user) {
return userDao.save(user);
}

/**
* 依据 Id,获取账号
*
* @param userId
* @return
*/
public User getUser(Long userId) {
return userDao.get(userId);
}

/**
* 更新账号所对应的密码
*  @param userId
* @param pwd
*/
public int update(Long userId, String pwd) {
return userDao.update(userId, pwd);
}
}

希望让 get***() 方法拥有只读事务,其它方法拥有写事务。对这一业务要求,我们可以使用 aop/tx 命名空间来配置。

spring_tx.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:p="http://www.springframework.org/schema/p"
xmlns:context="http://www.springframework.org/schema/context"
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-4.0.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-4.0.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-4.0.xsd
">

<!-- 扫描包含注解定义的类包-->
<context:component-scan base-package="net.deniro.xxx.transaction.xml"/>

<!-- 数据源-->
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"
destroy-method="close"
p:driverClassName="com.mysql.jdbc.Driver"
p:url="jdbc:mysql://127.0.0.1:3306/spring4"
p:username="root"
p:password="xxx"/>

<!-- JDBC 模板-->
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate"
p:dataSource-ref="dataSource"
/>

<!-- 事务管理器-->
<bean id="transactionManager"
class="org.springframework.jdbc.datasource.DataSourceTransactionManager"
p:dataSource-ref="dataSource"/>

<!-- 增强事务-->
<tx:advice id="txAdvice" transaction-manager="transactionManager">
<tx:attributes>
<tx:method name="get*" read-only="false"/>
<tx:method name="add*" rollback-for="Exception"/>
<tx:method name="update"/>
</tx:attributes>
</tx:advice>

<!-- 定义需要增强的目标方法-->
<aop:config>
<!-- 增强切面-->
<aop:pointcut id="serviceMethod" expression="exec。ution(* net.deniro.xxx.transaction.xml.UserService.*(..))"/>
<aop:advisor advice-ref="txAdvice" pointcut-ref="serviceMethod"/>
</aop:config>

</beans>

在 aop 命名空间中,通过切点表达式,将 net.deniro.xxx.transaction.xml.UserService 中的所有方法,都纳入了事务增强的管理范围。

其中,最关键的是

<tx:method>
元素,它拥有如下属性:

属性 是否必须 默认值 说明
name 必须 相关联的方法名。可以使用通配符(*)。 形如:get*、add* 等。
propagation - REQUIRED 事务传播行为,可选值为:REQUIRED、SUPPORTS、MANDATORY、REQUIRES_NEW、NOT_SUPPORTED、NEVER、NESTED
isolation - DEFAULT 事务隔离级别,可选值为:DEFAULT、READ_UNCOMMITTED、READ_COMMITTED、REPEATABLE_READ、SERIALIZABLE
timeout - -1 事务超时时间(单位为 s)。如果为 -1,则事务的超时时间由底层事务系统决定。
read-only - false 是否只读
rollback-for - 所有运行期异常,都回滚 触发事务回滚的 Excepiton 名称,多个以逗号隔开。
norollback-for 所有检查型异常,都不回滚 不触发事务回滚的 Excepiton 名称,多个以逗号隔开。

基于 aop/tx 来配置声明式事务管理,是实际项目中最常使用的配置方式,因为它的表达能力最强而且使用也最为灵活 。

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: