这篇笔记来学习一下使用Spring框架的时候,@Transactional注解标注的方法在什么情况下事务不会生效。
我们可以写一个demo项目,
引入以下依赖
<dependencies>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.6</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>5.2.8.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.2.8.RELEASE</version>
</dependency>
</dependencies>
项目的目录结构如下:
我们新建一个user表,之后会用上
CREATE TABLE `tb_user` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`name` varchar(255) NOT NULL DEFAULT '',
`age` int(11) NOT NULL DEFAULT '0',
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=50 DEFAULT CHARSET=utf8
然后我们需要在 site.nemo.entity 包里面定义一个User类:
package site.nemo.entity;
public class User {
private Integer id;
private String name;
private Integer age;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
@Override
public String toString() {
return "User{" +
"id=" + id +
", name='" + name + '\'' +
", age=" + age +
'}';
}
}
然后我们还需要一个Dao,来操作user表。在 site.nemo.dao 包下新建一个UserDao类:
@Repository
public class UserDao {
@Autowired
private JdbcTemplate jdbcTemplate;
public void save(User user) {
jdbcTemplate.update("insert into tb_user (name, age) values (?, ?)", user.getName(), user.getAge());
}
}
然后我们还需要对jdbc的数据源进行一些配置,在 site.nemo.configuration 包里面新建一个配置类:
@Configuration
@ComponentScan(basePackages = {"site.nemo.service", "site.nemo.dao"})
public class TransactionConfiguration {
@Bean
public JdbcTemplate jdbcTemplate() {
return new JdbcTemplate(dataSource());
}
@Bean
public DataSource dataSource() {
DriverManagerDataSource dataSource = new DriverManagerDataSource();
dataSource.setDriverClassName("com.mysql.jdbc.Driver");
dataSource.setUrl("jdbc:mysql://xxx.xxx.xxx.xxx:3306/mytestdb?characterEncoding=utf8");
dataSource.setUsername("xxxx");
dataSource.setPassword("xxxx");
return dataSource;
}
}
最后我们在 site.nemo.service 里面新建一个UserService:
@Service
public class UserService {
@Autowired
private UserDao userDao;
}
我们下面开始分析几个@Transactional没有起作用的原因
原因一:没有开启事务管理
我们给 UserService 添加一个方法,如下所示。
@Transactional
public void sav