一、踩到小坑
application.yml的jpa,hibernate配置如下
spring:
jpa:
hibernate:
ddl-auto: update
show-sql: true
一个Servicer如下
@Service
public class GirlService {
@Autowired
private GirlRepository repository; //数据库操作类
@Transactional
public void insertTwo(){
Girl girl1 = new Girl();
girl1.setName("AA");
girl1.setSalary(810000.0);
repository.save(girl1);
Girl girl2 = new Girl();
girl2.setName("BBBBBBBBBBBBBBBBBBBB"); //name字段在数据库定义的长度是10,所以这里会出错
girl2.setSalary(820000.0);
repository.save(girl2);
}
}
执行之后,事务始终没有回滚:girl1总是“成功”地写入了数据库。
二、搬土填坑
(1)检查注解引用没有问题,用的是org.springframework.transaction.annotation.Transactional
。
(2)检查数据库引擎类型,没有问题,
show variables like '%storage_engine%';
查询结果:
variable_name | value |
---|---|
default_storage_engine | InnoDB |
default_tmp_storage_engine | InnoDB |
disabled_storage_engines | |
internal_tmp_disk_storage_engine | InnoDB |
(3)根据网上一些解答说“ Spring 设计的 @Transactional 注解被指定为只对 RuntimeException 及其子类的异常才会进行事务回滚。如果想要让 Spring 能对所有出现的异常都进行回滚的话,可以在尝试在使用 @Transactional 注解时指定回滚的异常类型,写法如下:@Transactional(rollbackFor=Exception.class)”。
于是写@Transactional(rollbackFor=Exception.class),没能解决;写@Transactional(rollbackFor=DataException.class),也没能解决。
✔✔✔
检查数据库表引擎类型
show create table girl;
查询结果显示:
CREATE TABLE `girl` ( `id` int(11) NOT NULL, `name` varchar(10) DEFAULT NULL, `salary` double DEFAULT NULL, PRIMARY KEY (`id`)) ENGINE=MyISAM DEFAULT CHARSET=utf8
原来该表是MyISAM引擎,不支持事务
(1)修改该表引擎alter table girl engine =innodb
,再执行代码,事务成功回滚;
(2)据说spring boot2.0中的hibernate创建的表默认就是MyISAM引擎,但是可以通过修改配置文件,使自动创建的表是InnoDB引擎类型。我在application.yml中增加了以下配置
spring.jpa.database-platform: org.hibernate.dialect.MySQL5InnoDBDialect #不加这句则默认为myisam引擎
,再建新表就是InnoDB引擎类型,支持事务。