一、配置环境
1.向pom.xml中添加数据库驱动、数据源、spring-jdbc模块依赖。
具体向pom.xml添加如下依赖如下:
<!--数据库驱动--> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>5.1.47</version> </dependency> <!--数据库连接池--> <dependency> <groupId>c3p0</groupId> <artifactId>c3p0</artifactId> <version>0.9.1.2</version> </dependency> <!--spring对jdbc进行封装--> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-jdbc</artifactId> <version>5.1.4.RELEASE</version> </dependency>
二. 配置数据源和JdbcTemplate
第一种:
Configuration配置类如下:
@Configuration @EnableTransactionManagement public class TransactionConfiguration { @Bean public DataSource dataSource() throws Exception { ComboPooledDataSource dataSource = new ComboPooledDataSource(); dataSource.setUser("root"); dataSource.setPassword("123456"); dataSource.setJdbcUrl("jdbc:mysql://localhost:3306/ctsimdm_master"); dataSource.setDriverClass("com.mysql.jdbc.Driver"); return dataSource; } @Bean public JdbcTemplate jdbcTemplate() throws Exception { //dataSource()这里调用并不会重复创建dataSource实例,如果容器存在,则会查找已存在实例 JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource()); return jdbcTemplate; } //注册事务管理器在容器中 @Bean public PlatformTransactionManager transactionManager() throws Exception{ return new DataSourceTransactionManager(dataSource()); } }
第二种:
Configuration配置类如下:
@Configuration @EnableTransactionManagement @PropertySource("jdbc.properties") public class TransactionConfiguration implements EmbeddedValueResolverAware { private StringValueResolver valueResolver; // @Profile("dev")//如果加了这个注解,则默认是不加载到容器中的 @Bean("devDataSource") public DataSource dataSourceDevelop(@Value("${db.password}") String pwd) throws Exception { String driverClass = valueResolver.resolveStringValue("${db.driverClass}"); ComboPooledDataSource dataSource = new ComboPooledDataSource(); dataSource.setUser("root"); dataSource.setPassword(pwd); dataSource.setJdbcUrl("jdbc:mysql://localhost:3306/ctsimdm_master"); dataSource.setDriverClass(driverClass); return dataSource; } @Bean public JdbcTemplate jdbcTemplate(@Qualifier DataSource devDataSource) throws Exception { JdbcTemplate jdbcTemplate = new JdbcTemplate(devDataSource); return jdbcTemplate; } //注册事务管理器在容器中 @Bean public PlatformTransactionManager transactionManager() throws Exception{ return new DataSourceTransactionManager(dataSource()); } public void setEmbeddedValueResolver(StringValueResolver resolver) { this.valueResolver = resolver; } }
其中jdbc.properties文件如下:
db.user=root db.password=123456 db.driverClass=com.mysql.jdbc.Driver
三、创建数据库及表
1.创建数据库db_test
create database db_test;
2.创建数据表tb_user
CREATE TABLE `tb_user` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(50) DEFAULT NULL,
`age` int(2) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
四、创建测试类
1. 创建UserDao
@Repository public class UserDao { @Autowired private JdbcTemplate jdbcTemplate; public void insert() { String sql = "INSERT INTO tb_user(name, age) " + "VALUES (?, ?)"; jdbcTemplate.update(sql, new Object[]{"admin", 18}); } }
2. 创建service
@Service public class UserService { @Autowired private UserDao userDao; @Transactional //该注解表示insertUser方法以事务的方式执行 public void insertUser() { userDao.insert(); System.out.println("插入完成"); System.out.println(1/0); //这里会报数学错误,执行到这里,事务会回滚 } }
3. 创建测试主类
public class MainTest { public static void main(String[] args) { //启动容器,TransactionConfiguration是对应的配置类 ApplicationContext applicationContext = new AnnotationConfigApplicationContext(TransactionConfiguration.class); UserService userService = applicationContext.getBean(UserService.class); userService.insertUser(); } }
五、测试
1. 删掉@Transactional注解,执行MainTest.main()方法。看到结果:
报java.lang.ArithmeticException: / by zero异常,但是数据正常插入到数据库中:
2.在insertUser方法上加上@Transactional注解,执行MainTest.main()方法。看到结果:
报java.lang.ArithmeticException: / by zero异常,但是数据库未插入新数据:
3.再次删除@Transactional注解,执行MainTest.main()方法。看到结果:
同样报错,数据插入结果如下:
六、总结
1.在测试的第2步和第3步,事务在回滚时,导致id自增。
2.在使用@Transactional注解时,两种打开事务管理的方式:
第一种:要再Configuration类中加入@EnableTransactionManagement注解,以开启事务管理。
第二种:在使用application.xml配置文件时,也可以使用<tx:annotation-driven/>来打开事务管理。