声明式事务配置有两种:
- 使用
XML
配置,使用AOP
织入管理事务,可以做到无侵入; - 使用
Java
或XML
配置,只需要一个@Transactional
注解侵入而已,相对与AOP
织入配置更简洁。
在 Spring Boot 项目中,事务相关的组件已经配置好了,直接使用 @Transactional 注解即可
1. 基于XML的AOP织入配置
配置 事务管理器:
<bean class="org.springframework.jdbc.datasource.DriverManagerDataSource" id="dataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://127.0.0.1/demo?useUnicode=true&characterEncoding=utf-8"/>
<property name="username" value="root"/>
<property name="password" value="123"/>
</bean>
<bean class="org.springframework.jdbc.datasource.DataSourceTransactionManager" id="txManager">
<property name="dataSource" ref="dataSource"/>
</bean>
<bean class="org.springframework.jdbc.core.JdbcTemplate" id="jdbcTemplate">
<property name="dataSource" ref="dataSource"/>
</bean>
配置 事务通知:
<tx:advice transaction-manager="txManager" id="txAdvice">
<tx:attributes>
<!-- 给那些方法配置事务属性,如 事务传播性、事务隔离性 -->
<tx:method name="update" propagation="REQUIRED"/>
<tx:method name="save"/>
</tx:attributes>
</tx:advice>
配置 AOP事务的切入:
<aop:config>
<!-- 指定切入到 AccountDAO 类的所有方法中 -->
<aop:pointcut id="test" expression="execution(* ctd.demo.AccountDAO.*(..))"/>
<aop:advisor advice-ref="txAdvice" pointcut-ref="test"/>
</aop:config>
通过以上配置后,AccountService 类的相关方法具备了事务管理
public class AccountService {
@Autowired
JdbcTemplate jdbcTemplate;
public void update(){
jdbcTemplate.update("update account_tbl set money=300 where name=?", "li");
}
public void save(){
...
}
}
2. 使用 @Transactional 注解的配置
我们这里的配置都是基于传统的Spring项目来做的,SpringBoot项目已经自动配置集成好了的。
2.1 Java 配置
@Configuration
@ComponentScan
@EnableTransactionManagement //开启事务注解支持
public class JavaConfig {
@Bean
DataSource dataSource() {
DriverManagerDataSource ds = new DriverManagerDataSource();
ds.setPassword("123");
ds.setUsername("root");
ds.setUrl("jdbc:mysql://127.0.0.1/demo?useUnicode=true&characterEncoding=utf-8");
ds.setDriverClassName("com.mysql.jdbc.Driver");
return ds;
}
@Bean
JdbcTemplate jdbcTemplate(DataSource dataSource) {
return new JdbcTemplate(dataSource);
}
@Bean
PlatformTransactionManager transactionManager() {
return new DataSourceTransactionManager(dataSource);
}
}
其实配置跟 XML
的差不多,但有个关键点:
- 使用
@EnableTransactionManagement
注解开启事务支持
之后,我们就可以方法上使用 @Transactional
注解了
@Transactional
public void update() {
jdbcTemplate.update("update account_tbl set money=300 where name=?", "li");
int i = 1 / 0;
}
2.2 XML
配置
<bean class="org.springframework.jdbc.datasource.DriverManagerDataSource" id="dataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://127.0.0.1/demo?useUnicode=true&characterEncoding=utf-8"/>
<property name="username" value="root"/>
<property name="password" value="123"/>
</bean>
<!-- 1. 声明 JDBC的事务管理器 -->
<bean class="org.springframework.jdbc.datasource.DataSourceTransactionManager" id="txManager">
<property name="dataSource" ref="dataSource"/>
</bean>
<!-- 2. 对 @Transactional注解的Bean进行自动事务织入 -->
<tx:annotation-driven transaction-manager="txManager" proxy-target-class="true"/>
<tx:annotation-driven>
等同于 @EnableTransactionManagement
开启事务 。通过以上配置也启用了 @Transactional
注解。
@Transactional
public void update() {
jdbcTemplate.update("update account_tbl set money=300 where name=?", "li");
int i = 1 / 0;
}
@Transactional
注解可以加在方法上,也可以加在类上:
当
@Transactional
注解加在类上,表示该类的所有方法都有事务;该注解加在方法上,表示该方法有事务。
3. 总结
通过上面对声明式事务的配置及使用,使我们更能清晰的发现 基于XML的AOP配置
与 @Transactional
的差别和共性。