如何在AOP建议中将日志保存到数据库

时间:2019-06-24 14:25:33

标签: spring spring-boot aop spring-aop

使用Spring AOP时,我在将日志(或任何其他信息)保存在数据库中时遇到问题。

这是问题的根源:

@Aspect
@Configuration
@Component
@EnableAspectJAutoProxy
public class LoggingAspect {

    @Autowired
    private LogService logService;

    @AfterThrowing(pointcut = "execution(* org.springframework.web.client.RestTemplate+.*(..))", throwing = "ex")
    public void logError(Exception ex) {
        Log log = new Log("Error!");
        logService.save(log);
    }
}

logService实例是一个简单的@Service类,它在内部调用@Repository方法。没什么特别的。 Log类更简单:)它仅包含一个变量(如果包含id,则包含两个):

@Entity
@Table
public class Log {
    @Id
    private Long id;

    @Column
    private String message;

    //getters, setters, constructors, etc.
}

LoggingAspect正常工作。如有任何异常,@AfterThrowing通知会被正确调用。但是在调用save方法之后,什么都不会保存在db中。 当我尝试调用getAll()方法而不是save时,一切正常。所有数据均从数据库加载。 此问题仅适用于save方法。

如果有任何提示,我将不胜感激。

编辑:
如前所述,@Service@Repository类目前非常基础。也许值得添加外部方面类,使一切运行正常。可以将日志保存在数据库中。仅在保存时才发生此问题,并且仅在各种建议中使用时才发生此问题。 已添加服务代码

@Service
public class LogService {

    @Autowired
    private LogRepository logRepository;

    @Transactional(readOnly = true)
    public List<Log> getAllLogs() {
        return logRepository.findAll();
    }

    @Transactional
    public void save(Log log) {
        logRepository.save(log);
    }
}

已添加存储库代码

@Repository
public interface LogRepository extends JpaRepository<Product, Log> {
}

2 个答案:

答案 0 :(得分:1)

听起来像交易处理。

但是更多信息会很好,我只能在这里猜测。这么点检查,如果您还没有的话。

我猜您在服务或存储库上使用了@Transational,对吗?从Spring默认的代理机制开始,还要确保您在单独的类中具有Repository,Service。

调试并添加jpa,hibernate和spring事务的日志记录。

答案 1 :(得分:0)

好的。我找到了解决方案! 我怀疑这是交易问题。无论任何现有事务如何,都必须开始一个新事务。因此@Service类中缺少一行(或更确切地说是交易属性)

@Transactional(propagation = Propagation.REQUIRES_NEW)
public void save(Log log) {
    logRepository.save(log);
}

感谢所有帮助解决问题的人。