在 Spring Boot 开发中,我们时常遇到需要在一个类的内部调用自己的其他方法,并且这些方法可能需要事务支持。这种场景通常发生在业务逻辑较为复杂的服务类中,其中一些操作需要确保数据的一致性和完整性。本文将以 MediaFileServiceImpl 类为例,探讨如何在 Spring Boot 中有效地使用当前类的代理类来处理内部事务。
一、场景描述
考虑一个典型的例子:在 MediaFileServiceImpl 服务类中,upload 方法需要调用 upload2Mysql 方法。这里,upload2Mysql 方法是事务性的,意味着它涉及到数据库操作,这些操作需要在一个事务中被处理。如果直接在 upload 方法中调用 upload2Mysql,由于 Spring 的代理方式,事务管理可能不会被正确应用,因为实际上是在同一个实例内部进行方法调用,绕过了 Spring 的代理。
<select id="selectChaptersWithResources" resultMap="ChapterDtoMap"> SELECT c.id AS chapter_id, c.parent_id, c.name, c.courseId, sc.id AS sub_chapter_id, sc.parent_id AS sub_parent_id, sc.name AS sub_name, sc.courseId AS sub_courseId, r.id AS resource_id, r.section_id, r.name AS resource_name FROM chapter c LEFT JOIN chapter sc ON c.id = sc.parent_id LEFT JOIN resource r ON sc.id = r.section_id WHERE c.courseId = #{courseId} AND c.parent_id IS NULL </select>
</mapper>
三、其他文件
1. Mapper
language-java
1 2 3 4
public interface ChapterMapper { List<ChapterDto> selectChaptersWithResources(Long courseId); }
2. Service
language-java
1 2 3 4 5 6 7 8 9 10 11
@Service public class ChapterService { @Autowired private ChapterMapper chapterMapper;
public List<ChapterDto> getChaptersWithResources(Long courseId) { return chapterMapper.selectChaptersWithResources(courseId); } }
3. Controller
language-java
1 2 3 4 5 6 7 8 9 10 11 12 13 14
@RestController @RequestMapping("/chapters") public class ChapterController { @Autowired private ChapterService chapterService;
@GetMapping("/{courseId}") public ResponseEntity<List<ChapterDto>> getChapters(@PathVariable Long courseId) { List<ChapterDto> chapters = chapterService.getChaptersWithResources(courseId); return ResponseEntity.ok(chapters); } }