Before using @Transaction
, my business code model was probably as follows:
DefaultTransactionDefinition def = new DefaultTransactionDefinition();
def.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED);
TransactionStatus transactionStatus = dataSourceTransactionManager.getTransaction(def);
try {
studentMapper.insertOnestdent(student);
logger.info("Insert one record successfully: " + student.toString());
} catch (Exception ex) {
dataSourceTransactionManager.rollback(transactionStatus);
// ex.printStackTrace();
logger.error("Insert one record unsuccessfully: " + student.toString());
return false;
}
dataSourceTransactionManager.commit(transactionStatus);
return true;
Similar to the above, no matter whether my above database operation is executed successfully or fails, I can get feedback in the log.
However, the above approach will cause a lot of code duplication. Such a logging function can be implemented using the aop provided by spring. However, after reading the document, I found that there is a @Transaction
annotation. Using this annotation, The code can be simplified as follows:
@Transactional(rollbackFor = Exception.class)
public boolean insertOneStudent(Student student) {
studentMapper.insertOneStudent(student);
logger.info("Insert one student successfully" + student.toString());
return true;
}
In this way, when the database operation is executed successfully, I can successfully record it in the log. But in this case, how should I record it in the log when the insertion operation fails.
My initial idea now is to manually implement a dynamic reflection function similar to @Transaction
, so that when every method that affects the data modification in the database is executed, I will be dynamically reflectinginvoke()
Exception handling try catch
is performed in the method. But I don’t know if spring has such a built-in function?
p.s: I try to put all database operations and processing at the service
level, and don’t want to throw log records above.
伊谢尔伦2017-06-06 09:53:47
insertOneStudent method entire try catch
try {
...
} catch (Exception e) {
logger.error(e.getMessage(), e);
throw e;
}
Or implement @RestControllerAdvice and print exception logs in it
Like this:
@RestControllerAdvice
public class MyExceptionHandler {
@ExceptionHandler(value = Exception.class)
public Object exceptionHandler(HttpServletRequest request,
Exception exception) {
logger.warn("异常:", exception);
...
}
}
世界只因有你2017-06-06 09:53:47
Spring also provides aspect exception handling
<!--aop配置 -->
<aop:config>
<!-- 业务类切面 -->
<aop:pointcut id="【切面ID】"
expression="【这里填写切面的匹配规则】" />
<!-- 异常处理 -->
<aop:aspect ref="【处理异常的类ID】">
<aop:after-throwing method="【处理异常的方法名称】" pointcut-ref="【切面ID】" throwing="e" />
</aop:aspect>
</aop:config>
Of course, if there is xml configuration, there will be annotation configuration. There are mainly the following comments
@Aspect declares aspect configuration
@Pointcut declares aspects
@AfterThrowing declaration processing method
Notes:
The class that handles exceptions does not need to implement any interface or inherit any class.
The method of handling exceptions needs to declare two parameters (you can also not declare it, the exception information cannot be obtained), for example
public void test(JoinPoint joinPoint, Exception e)
The joinPoint parameter can obtain the method parameter information that throws the exception. Needless to say, the Exception object.
The above content is for reference only. Different spring versions may cause the above instructions to be different from the actual situation. For standard instructions, please refer to Spring’s official documentation