Spring 中的事务主要是利用 Aop 思想,简化事务的配置,可以通过 Java 配置也可以通过 XML 配置。
我们通过一个转账操作来看下 Spring 中的事务配置。
准备工作
创建数据库 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 CREATE DATABASE `test01` ;USE `test01` ;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; insert into `account` (`id` ,`username` ,`money` ) values (1 ,'zhangsan' ,1000 ),(2 ,'lisi' ,1000 );
配置 JdbcTemplate 提供一个配置类,在配置类中配置 JdbcTemplate
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 @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()); } }
数据持久层 1 2 3 4 5 6 7 8 9 10 11 12 13 14 @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); } }
业务逻辑层 1 2 3 4 5 6 7 8 9 10 11 12 @Service public class UserService { @Autowired UserDao userDao; public void updateMoney () { userDao.addMoney("zhangsan" , 200 ); int i = 1 / 0 ; userDao.minMoney("lisi" , 200 ); } }
相关配置 最后,在 XML 文件中,开启自动化扫描:
1 2 3 4 5 6 7 8 9 10 11 12 <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
1 2 3 <bean class ="org.springframework.jdbc.datasource.DataSourceTransactionManager" id ="transactionManager" > <property name ="dataSource" ref ="dataSource" /> </bean >
2. 配置事务要处理的方法
1 2 3 4 5 6 7 8 <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
1 2 3 4 <aop:config > <aop:pointcut id ="pc1" expression ="execution(* com.antoniopeng.hello.spring.service.*.*(..))" /> <aop:advisor advice-ref ="txAdvice" pointcut-ref ="pc1" /> </aop:config >
4. 测试
1 2 3 4 5 6 7 8 9 10 11 @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 配置中添加如下配置:
1 <tx:annotation-driven transaction-manager ="transactionManager" />
这行配置,可以代替下面两个配置:
1 2 3 4 5 6 7 8 9 10 11 12 <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
注解,表示该方法开启事务,当然,这个注解也可以放在类上,表示这个类中的所有方法都开启事务。
1 2 3 4 5 6 7 8 9 10 11 12 13 @Service public class UserService { @Autowired UserDao userDao; @Transactional public void updateMoney () { userDao.addMoney("zhangsan" , 200 ); int i = 1 / 0 ; userDao.minMoney("lisi" , 200 ); } }
更多干货请移步:https://antoniopeng.com
If you like this blog or find it useful for you, you are welcome to comment on it. You are also welcome to share this blog, so that more people can participate in it. If the images used in the blog infringe your copyright, please contact the author to delete them. Thank you !