Spring Boot项目PostgreSQL数据莫名丢失问题排查求助
排查Spring Boot+PostgreSQL数据莫名丢失的方向
以下是针对你遇到的properties和property_details表数据丢失问题的具体排查步骤:
1. 检查事务回滚情况
- 排查Service层方法是否存在未捕获的RuntimeException:Spring默认会对未捕获的RuntimeException触发事务回滚,导致看似数据丢失但实际未提交到数据库。
- 检查是否手动设置了事务回滚:比如代码中调用
TransactionStatus.setRollbackOnly(),或者@Transactional注解的rollbackFor配置范围过大。 - 示例代码排查:
@Transactional public void saveProperty(Property property) { propertyRepository.save(property); // 此处若抛出未捕获RuntimeException,整个事务会回滚,数据不会持久化 throw new IllegalArgumentException("参数异常"); }
2. 验证数据库连接池与提交配置
- 检查连接池的
auto-commit设置:比如HikariCP的spring.datasource.hikari.auto-commit是否为true,若设为false且代码未手动提交事务,数据不会写入数据库。 - 排查原生JDBC/JdbcTemplate操作:如果使用了手动事务管理但未执行
commit(),同样会导致数据不持久化。 - 配置示例检查:
spring.datasource.hikari.auto-commit=true
3. 排查实体类级联操作与映射
- 检查
Property和PropertyDetails的关联注解:是否存在cascade=CascadeType.REMOVE或orphanRemoval=true?若删除主实体Property,会自动级联删除关联的PropertyDetails,即使代码未直接操作明细表。 - 实体类示例排查:
@Entity public class Property { @OneToMany(mappedBy = "property", cascade = CascadeType.REMOVE, orphanRemoval = true) private List<PropertyDetails> details; // 其他字段与方法 }
4. 检查数据库层面的触发器与外键约束
- 查询数据库是否存在自动删除数据的触发器:应用日志无法捕获数据库层面的触发器操作,需直接执行SQL排查:
SELECT tgname, pg_get_triggerdef(t.oid) FROM pg_trigger t JOIN pg_class c ON t.tgrelid = c.oid WHERE c.relname IN ('properties', 'property_details'); - 验证外键的
ON DELETE CASCADE约束:若其他表的外键关联到这两个表,当关联表记录被删除时,会触发级联删除当前表数据。
5. 确认数据是否真的丢失(而非查询逻辑问题)
- 直接用SQL在数据库客户端(如pgAdmin、psql)查询数据总量,排除代码查询时的过滤条件错误:
SELECT COUNT(*) FROM properties; SELECT COUNT(*) FROM property_details; - 检查查询代码是否存在错误的过滤条件(如状态、时间范围、分页参数),导致数据未被查询到而非实际丢失。
6. 排查多实例部署与环境配置
- 若为多实例部署,检查其他实例是否存在删除逻辑:是否有实例连接到同一数据库且执行了删除操作,但日志未统一收集。
- 确认所有实例的数据库连接配置:避免误连接到测试库或其他环境的数据库,导致数据被其他环境操作删除。
7. 检查PostgreSQL的WAL与恢复日志
- 查看PostgreSQL的WAL日志(默认在
pg_wal目录),或执行SQL查看WAL状态:SELECT * FROM pg_stat_wal; - 检查数据库的
postgresql.log,确认是否存在崩溃恢复、异常重启等可能导致数据回滚的记录。
内容的提问来源于stack exchange,提问作者shubham
相关产品推荐
相关产品推荐

