(八) 基于注解方式的声明事务管理
实现思路:
- 基于上篇
(七) 声明式事务管理
,进行略微修改,可以删除不要的aop包 applicationContext.xml
的修改- 在需要开启事务的方法上添加注解
2. applicationContext.xml
的修改
- 删除部分xml配置,和aop有关的配置
<!-- 通知 -->
<tx:advice id="txAdvice" transaction-manager="transactionManager">
<tx:attributes>
<tx:method name="*" propagation="REQUIRED" isolation="DEFAULT" read-only="false"/>
</tx:attributes>
</tx:advice>
<!-- aop切入 -->
<aop:config>
<aop:pointcut id="txPointcut" expression="execution(* com.dacangshu.dao.*.queryUser(..))"/>
<aop:advisor advice-ref="txAdvice" pointcut-ref="txPointcut"/>
</aop:config>
- 添加注解事务驱动
<!-- 注册事务管理驱动 -->
<tx:annotation-driven transaction-manager="transactionManager"/>
- 完整的xml如下,去掉了aop
<?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:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd">
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql:///jianghu?useSSL=false"/>
<property name="username" value="root"/>
<property name="password" value="asdasd"/>
</bean>
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
<property name="dataSource" ref="dataSource"/>
</bean>
<bean id="userDao" class="com.dacangshu.dao.UserDao">
<property name="jdbcTemplate" ref="jdbcTemplate"/>
</bean>
<!-- 事务管理器 -->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"/>
</bean>
<!-- 注册事务管理驱动 -->
<tx:annotation-driven transaction-manager="transactionManager"/>
</beans>
3.在需要开启事务的方法上添加注解 @Transactional
package com.dacangshu.dao;
import com.dacangshu.pojo.User;
import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.transaction.annotation.Transactional;
/**
* @author dacangshu
* @date 2021/5/11 19:07
*/
public class UserDao {
private JdbcTemplate jdbcTemplate;
public JdbcTemplate getJdbcTemplate() {
return jdbcTemplate;
}
public void setJdbcTemplate(JdbcTemplate jdbcTemplate) {
this.jdbcTemplate = jdbcTemplate;
}
// 这里添加注解
@Transactional
public void queryUser() {
jdbcTemplate.update("update MartialArts set power = power + 10 where aid = 1");
// 这里制造异常,让事务回滚
int i = 1 / 0;
jdbcTemplate.update("update MartialArts set power = power + 10 where aid = 2");
}
}
4. 测试
package com.dacangshu;
import com.dacangshu.dao.UserDao;
import org.springframework.context.support.ClassPathXmlApplicationContext;
/**
* @author dacangshu
* @date 2021/5/11 16:41
*/
public class BootStrap {
public static void main(String[] args) {
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
UserDao userDao = context.getBean("userDao", UserDao.class);
userDao.queryUser();
System.out.println(userDao);
}
}
输出:
Exception in thread "main" java.lang.ArithmeticException: / by zero
at com.dacangshu.dao.UserDao.queryUser(UserDao.java:30)
at
...
进程已结束,退出代码为 1
没有发生变化,已经回滚了。