温馨提示:文本由机器自动转译,部分词句存在误差,以视频为准
00:00
宠物医院要同时写主人、宠物和就诊记录三部,必须一起成功或一起失败。方法上写的事物注解,为什么有时还是各写各的?先别急着加注解,Owner pet visit三个写入应放进同一个服务方法,由数据库事务统一提交或回滚,边界放在业务动作上。我确实在service方法上加了事物注解,中间故意让visit插入失败,结果honor和pet还是写进去了,回滚没发生。先确认异常是不是运行时异常,再确认调用入口是否经过spring代理。同类内部方法直接调用,很可能绕开了代理对象。还要看数据库连接是否真的被同一个事物服用。连接池里每个连接独立事物没绑定到当前,线程回滚自然无从谈起。那我把内部调用改成通过代理对象调用,或者拆到另一个B,是不是就能让事务代理生效?
01:03
传播级别需要改吗?默认传播级别通常够用,但嵌套调用药明确加入已有事物还是新开事物。核心是让外层方法成为唯一事物边界。只读查询要单独标记,避免占用写事物。更危险的是把保险接口调用放进事物里,网络一慢,连接就被长期占住。长事物会拖垮连接池。保险HTTP调用如果放在提交前几十秒,不返回其他请求,只能排队等连接数据库,压力瞬间上来。所以正确顺序是先完成数据库写入并提交,再做保险调用。如果保险失败,用补偿或状态标记处理,而不是一直占着事物。对事物只覆盖数据库一致性边界外部调用放事物外,需要最终一致时,用状态字段加定时补偿,别用长事物硬扛。
02:05
所以,事务不生效,往往不是注解没写,而是代理没经过,边界没划清,外部调用没移出去。从记住注解到设计边界,才算真正落地。
我来说两句