Heim > Fragen und Antworten > Hauptteil
Bevor ich @Transaction
verwendete, sah mein Geschäftscodemodell wahrscheinlich wie folgt aus:
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;
Ähnlich wie oben kann ich im Protokoll eine Rückmeldung erhalten, unabhängig davon, ob mein obiger Datenbankvorgang erfolgreich ausgeführt wurde oder fehlschlägt.
Der obige Ansatz führt jedoch zu einer großen Codeduplizierung. Als ich mir das Dokument später ansah, stellte ich fest, dass es eine @Transaction
-Anmerkung gibt , der Code kann wie folgt vereinfacht werden:
@Transactional(rollbackFor = Exception.class)
public boolean insertOneStudent(Student student) {
studentMapper.insertOneStudent(student);
logger.info("Insert one student successfully" + student.toString());
return true;
}
Auf diese Weise kann ich den Datenbankvorgang erfolgreich im Protokoll aufzeichnen. Aber wie soll ich ihn in diesem Fall im Protokoll aufzeichnen, wenn der Einfügevorgang fehlschlägt?
Meine erste Idee besteht nun darin, eine dynamische Reflexionsfunktion ähnlich wie @Transaction
的动态反射的功能,这样每个要影响数据库中的数据修改的方法执行的时候我都在动态反射的invoke()
方法中进行异常的try catch
manuell zu implementieren, sodass ich bei der Ausführung jeder Methode, die sich auf die Datenänderung in der Datenbank auswirkt, die Ausnahmebehandlung invoke()
dynamisch widerspiegelt wird in der Methode try Catch
ausgeführt. Aber ich weiß nicht, ob der Frühling eine solche eingebaute Funktion hat?
ps.s: Ich versuche mein Bestes, alle Datenbankoperationen und -verarbeitungen auf der service
-Ebene abzuwickeln, und möchte keine Protokolldatensätze nach oben werfen.
伊谢尔伦2017-06-06 09:53:47
insertOneStudent方法整个try catch
try {
...
} catch (Exception e) {
logger.error(e.getMessage(), e);
throw e;
}
或者实现@RestControllerAdvice,在里面统一打印异常日志
像这样:
@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也有提供切面的异常处理
<!--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>
当然,有xml配置就会有注解配置。主要有下面几个注解
@Aspect 声明切面配置
@Pointcut 声明切面
@AfterThrowing 声明处理方法
注意事项:
处理异常的类是不需要实现任何接口和继承任何类的。
处理异常的方法要声明两个参数(不声明也可以,获取不了异常信息而已),举个例子
public void test(JoinPoint joinPoint, Exception e)
其中joinPoint参数可以获取抛出异常的方法参数信息,Exception对象就不用说了吧。
以上内容仅做参考,spring的版本不同也可能会导致上述说明和实际情况有差异,想获取标准的说明请参阅Spring的官方文档