1、在同一个类中,没有@Transactional注解的方法去调用有@Transactional注解
2、@Transactional注解修饰的方法不是public的
3、抛出的异常为checked类型
但今天比较倒霉了,@Transactional失效,都不是以上3个原因。
还原一下当时的情形:
配置文件application.properties:
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.url=jdbc:mysql://127.0.0.1:3306/dbgirl?useUnicode=true&characterEncoding=UTF-8
spring.datasource.username=root
spring.datasource.password=123456
spring.jpa.hibernate.ddl-auto=update
spring.jpa.database-platform=org.hibernate.dialect.MySQL5Dialect
User实体类:
@Entity
@Table(name = "users")
public class User {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
@Column(unique = true)
private String name;
private String company;
// 略去getter,setter
}
Service方法:
@Component
public class DemoService {
@Autowired
UserDao userDao;
@Autowired
OperationLogDao operationLogDao;
@Transactional
public void addUser(String name){
OperationLog log = new OperationLog();
log.setContent("create user:" + name);
operationLogDao.save(log);
User user = new User();
user.setName(name);
userDao.save(user);
}
}
本来想的很好,利用jpa自动生成数据库表结构,方便向users表插入记录。当重复插入同一个name的User时,会报Duplicate entry 的错误,然后导致回滚,但结果并没有。
后来搜了好久,才发现,mmp!
数据库里表的引擎是MyISAM,不支持事务处理。。关键在于application.properties中这一行配置:
spring.jpa.database-platform=org.hibernate.dialect.MySQL5Dialect
将其修改如下
spring.jpa.database-platform=org.hibernate.dialect.MySQL5InnoDBDialect
再重新生成表后,引擎变为Innodb,再调用addUser方法,报错以后,事务终于回滚了
作者:宁静的猫
链接:https://www.jianshu.com/p/68e49a81a7fa
来源:简书