spring 注解如何开启声明式事务
作者:很懒的十六
这篇文章主要介绍了spring 注解开启声明式事务问题,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
spring开启声明式事务
导入依赖
pom.xml
<dependencies> <!-- https://mvnrepository.com/artifact/org.springframework/spring-context --> <!--spring依赖--> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>4.3.12.RELEASE</version> </dependency> <!--单元测试依赖--> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.13</version> <scope>test</scope> </dependency> <!--mysql驱动--> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>8.0.21</version> </dependency> <!-- https://mvnrepository.com/artifact/c3p0/c3p0 --> <!--c3p0数据源--> <dependency> <groupId>c3p0</groupId> <artifactId>c3p0</artifactId> <version>0.9.1.2</version> </dependency> <!--spring jdbc spring操作数据库--> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-jdbc</artifactId> <version>4.3.12.RELEASE</version> </dependency> </dependencies>
操作数据库需要配置数据源,spring提供的操作数据库的JdbcTemplate创建时需要传入数据源,事务管理器创建时也需要传入数据源,然后将数据源,JdbcTemplate,事务管理器注册到容器中
具体代码如下:
配置类文件
SpringTxConfig.java
package com.sixteen.tx; import com.mchange.v2.c3p0.ComboPooledDataSource; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.jdbc.datasource.DataSourceTransactionManager; import org.springframework.transaction.PlatformTransactionManager; import org.springframework.transaction.annotation.EnableTransactionManagement; import javax.sql.DataSource; import java.beans.PropertyVetoException; @ComponentScan(basePackages = {"com.sixteen.tx"})//包扫描 @Configuration @EnableTransactionManagement//开启基于注解的声明式事务 public class SpringTxConfig { //注册数据源 @Bean public DataSource dataSource() throws PropertyVetoException { ComboPooledDataSource dataSource = new ComboPooledDataSource(); dataSource.setDriverClass("com.mysql.cj.jdbc.Driver"); dataSource.setPassword("123456"); dataSource.setUser("root"); dataSource.setJdbcUrl("jdbc:mysql://localhost:3306/jdbc?serverTimezone=Asia/Shanghai&useSSL=true&useUnicode=true&characterEncoding=UTF-8"); return dataSource; } //注册JdbcTemplate @Bean public JdbcTemplate jdbcTemplate() throws PropertyVetoException { //两种方法获取DataSource //1. 直接在方法放置参数 public JdbcTemplate jdbcTemplate(DataSource dataSource) // 默认会去容器中获取 //2. 如下: 调用上面的方法 //spring对@Configuration类有特殊处理,注册组件的方法多次调用只是在IOC容器中找组件 return new JdbcTemplate(dataSource()); } //注册事务管理器 @Bean public PlatformTransactionManager transactionManager() throws PropertyVetoException { return new DataSourceTransactionManager(dataSource());//需要传入dataSource } }
ps: 我用的mysql是8.0+版本,编写jdbcUrl时至少需要附带时区参数:serverTimezone=Asia/Shanghai
在此之前需要在mysql数据库中建一张普通的User表,如下所示:(id自增)
id | name |
---|---|
1 | zhangsan |
业务逻辑编写
UserDao.java
package com.sixteen.tx; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.stereotype.Repository; import java.util.UUID; @Repository public class UserDao { @Autowired private JdbcTemplate jdbcTemplate; public void insert(){ String sql = "INSERT INTO `user`(name) VALUES(?)"; String name = UUID.randomUUID().toString().substring(0, 5); jdbcTemplate.update(sql,name); } }
UserService.java
package com.sixteen.tx; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @Service public class UserService { @Autowired private UserDao userDao; @Transactional public void insertUser(){ userDao.insert(); System.out.println("插入完成"); //故意制造错误,使事务生效,进行回滚 int i = 10/0; } }
测试代码
SpringTxTest.java
package com.sixteen.test; import com.sixteen.tx.SpringTxConfig; import com.sixteen.tx.UserService; import org.junit.Test; import org.springframework.context.annotation.AnnotationConfigApplicationContext; public class SpringTxTest { @Test public void testInsert(){ AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(SpringTxConfig.class); UserService service = context.getBean(UserService.class); service.insertUser(); } }
总结
以上就是spring如何用注解方式开启声明式事务,细节之处可能没有讲到,但基本的实现还是有的,若有不足之处望见谅并指出。
这些仅为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。