Spring 事务解决方案
2021-01-13 22:38
1356 查看
Spring 中的事务主要是利用 Aop 思想,简化事务的配置,可以通过 Java 配置也可以通过 XML 配置。
我们通过一个转账操作来看下 Spring 中的事务配置。
准备工作
创建数据库
CREATE DATABASE /*!32312 IF NOT EXISTS*/`test01` /*!40100 DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci */ /*!80016 DEFAULT ENCRYPTION='N' */; USE `test01`; /*Table structure for table `account` */ DROP TABLE IF EXISTS `account`; CREATE TABLE `account` ( `id` int(11) NOT NULL AUTO_INCREMENT, `username` varchar(255) COLLATE utf8mb4_general_ci DEFAULT NULL, `money` int(11) DEFAULT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci; /*Data for the table `account` */ insert into `account`(`id`,`username`,`money`) values (1,'zhangsan',1000),(2,'lisi',1000);
配置 JdbcTemplate
提供一个配置类,在配置类中配置
JdbcTemplate
@Configuration public class JdbcConfig { @Bean DataSource dataSource() { DriverManagerDataSource dataSource = new DriverManagerDataSource(); dataSource.setDriverClassName("com.mysql.cj.jdbc.Driver"); dataSource.setUsername("root"); dataSource.setPassword("123456"); dataSource.setUrl("jdbc:mysql:///test01"); return dataSource; } @Bean JdbcTemplate jdbcTemplate() { return new JdbcTemplate(dataSource()); } }
数据持久层
@Repository public class UserDao { @Autowired JdbcTemplate jdbcTemplate; public void addMoney(String username, Integer money) { jdbcTemplate.update("update account set money=money+? where username=?", money, username); } public void minMoney(String username, Integer money) { jdbcTemplate.update("update account set money=money-? where username=?", money, username); } }
业务逻辑层
@Service public class UserService { @Autowired UserDao userDao; public void updateMoney() { userDao.addMoney("zhangsan", 200); int i = 1 / 0; userDao.minMoney("lisi", 200); } }
相关配置
最后,在 XML 文件中,开启自动化扫描:
<context:component-scan base-package="com.antoniopeng"/> <bean class="org.springframework.jdbc.datasource.DriverManagerDataSource" id="dataSource"> <property name="username" value="root"/> <property name="password" value="123456"/> <property name="url" value="jdbc:mysql:///test01?serverTimezone=Asia/Shanghai"/> <property name="driverClassName" value="com.mysql.cj.jdbc.Driver"/> </bean> <bean class="org.springframework.jdbc.core.JdbcTemplate" id="jdbcTemplate"> <property name="dataSource" ref="dataSource"/> </bean>
XML 配置
XML 中配置事务一共分为三个步骤:
1. 配置 TransactionManager
<bean class="org.springframework.jdbc.datasource.DataSourceTransactionManager" id="transactionManager"> <property name="dataSource" ref="dataSource"/> </bean>
2. 配置事务要处理的方法
<tx:advice id="txAdvice" transaction-manager="transactionManager"> <tx:attributes> <tx:method name="update*"/> <tx:method name="insert*"/> <tx:method name="add*"/> <tx:method name="delete*"/> </tx:attributes> </tx:advice>
注意,一旦配置了方法名称规则之后,service 中的方法一定要按照这里的名称规则来,否则事务配置不会生效
3. 配置 AOP
<aop:config> <aop:pointcut id="pc1" expression="execution(* com.antoniopeng.hello.spring.service.*.*(..))"/> <aop:advisor advice-ref="txAdvice" pointcut-ref="pc1"/> </aop:config>
4. 测试
@Before public void before() { ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml"); jdbcTemplate = ctx.getBean(JdbcTemplate.class); userService = ctx.getBean(UserService.class); } @Test public void test1() { userService.updateMoney(); }
Java 配置
如果要开启 Java 注解配置,在 XML 配置中添加如下配置:
<tx:annotation-driven transaction-manager="transactionManager" />
这行配置,可以代替下面两个配置:
<tx:advice id="txAdvice" transaction-manager="transactionManager"> <tx:attributes> <tx:method name="update*"/> <tx:method name="insert*"/> <tx:method name="add*"/> <tx:method name="delete*"/> </tx:attributes> </tx:advice><aop:config> <aop:pointcut id="pc1" expression="execution(* org.javaboy.service.*.*(..))"/> <aop:advisor advice-ref="txAdvice" pointcut-ref="pc1"/> </aop:config>
然后,在需要添加事务的方法上,添加
@Transactional注解,表示该方法开启事务,当然,这个注解也可以放在类上,表示这个类中的所有方法都开启事务。
@Service public class UserService { @Autowired UserDao userDao; @Transactional public void updateMoney() { userDao.addMoney("zhangsan", 200); int i = 1 / 0; userDao.minMoney("lisi", 200); } }
相关文章推荐
- Spring 整合Hibernate 事务代理类解决方案
- Spring Jersey Mybatis Aop transaction事务失效解决方案SpringManagedTransaction will not be managed by Spring
- Spring+SpringMVC 配置事务管理无效原因及解决方案。
- 【spring源码学习】spring的aop目标对象中进行自我调用,且需要实施相应的事务定义的解决方案
- Spring事务内多线程处理-解决方案
- spring事务使用+常见出错解决方案
- SpringMVC+Mybatis 事务不生效的解决方案
- spring下hibernate多数据库解决方案,以及跨库事务的尝试
- 关于使用mybatis-plus 的 dynamic-datasource-spring-boot-starter 动态数据源插件时无发使用事务的解决方案
- Spring配置多数据源在配置事务后无效完美解决方案
- springcloud+feign 集成LCN5.0.2分布式事务,以及全局异常捕获问题的解决方案
- 抛出自定义异常,spring AOP事务不回滚的解决方案
- Spring重复扫描导致事务失败的解决方案及深入分析
- Spring配置多数据源在配置事务后无效完美解决方案
- 抛出自定义异常,spring AOP事务不回滚的解决方案
- Spring配置多数据源在配置事务后无效完美解决方案
- Spring配置多数据源在配置事务后无效完美解决方案
- Spring+SpringMVC 配置事务管理无效原因及解决方案。
- Spring事务失效问题分析及解决方案
- SPRING事务逻辑探究和多数据源解决方案调研