1.dao层我是直接抛出异常,都是比较“底层”的异常,比如DataAccessException. 不捕获的原因是,假如service调用了多个dao方法,其中有一个发生了异常,如果该dao方法自己捕获了又没有重新抛出来。这时候,service事务没法回滚,因为它以为都执行正确了。
2.在service里, 调用的dao方法有可能抛出DataAccessException的话,那么service也不捕获。因为DataAccessException是runtime异常,无需强制try-catch,况且,如果你捕获了又没有抛出来,配置的事务没法感知到,因为默认只处理runtime异常,当然可以配置。
3.还可以这样,在service方法里,dao方法外面直接try-catch(Throwable e). 然后重新抛出自定义的业务相关的异常。比如TopicUpdateException.
问题:上面1,2,3我对dao层,service层的方法处理是否合理。2,3哪种更好些?为什么?
4.接上面,这个自定义的业务异常的粒度要控制到什么级别?能否举个例子
5.上面2,3 我都是用的aop统一处理异常。我看大部分人也推荐这么做。因为service层各个方法里catch里的逻辑大都相似。使用aop统一处理,好处是显而易见的。我想知道,有什么弊端吗?因为我发现公司项目几乎没有这么做的。都是直接try-catch,返回结果。要么就是上面2里提到的不捕获。出了异常反正可以记录在log里
请大家帮忙看看
Thanks for the invitation! But I have to declare that I am not an expert |_|
Question: Is my approach to the dao layer and service layer in steps 1, 2, and 3 above reasonable? Which one is better, 2 or 3?
First of all, I agree with your analysis and understanding in steps 1, 2, and 3. Secondly, I think
3
的处理更为妥帖,因为service
层就已经不是纯粹的数据交互,而是包含了一系列业务逻辑的操作,通过捕获Throwable
then throw a more meaningful (accurately describing the error) exception, whether it is recorded in the log or transaction processing, this is more suitable for possible subsequent remediation/error troubleshooting4. Continuing from the above, to what level should the granularity of this custom business exception be controlled? Can you give me an example
The granularity depends on the requirements. For example, if you only want to do rollback, then as long as you can locate something
service
错了对你来说就够了。但如果还希望进一步排查root cause
, would it be better to add more descriptions about the source error in the exception information?5. In the above 2 and 3, I used aop to handle exceptions uniformly. I think most people recommend this. Because the logic in the catch in each method of the service layer is mostly similar. The benefits of using aop for unified processing are obvious. I want to know, are there any disadvantages? Because I found that almost no company projects do this. They are all direct try-catch and return results. Or it's the non-capture mentioned in 2 above. If an exception occurs, it can be recorded in the log
First of all, let’s talk about why your company didn’t do that. This may be a historical reason. People who built the framework before
aop
认识不足,或者把个人喜好带到了工作中导致选择了直接到处try catch
(这种方式简单粗暴,最易掌握),aop
regarded it as a design paradigm. Whether architects or programmers, if they want to master it proficiently and use it freely, they still need to learn the cost ( This may be considered a disadvantage). If you are interested in the reason, it is best to chat with a few senior colleagues in private, maybe you can get some other inside information^^Regarding "any exceptions can be recorded in the log anyway", the idea is not wrong, but people who have actually dealt with error messages in massive logs will understand. It is obvious that it can be handled uniformly, but it is not done. This is considered a design flaw or mistake. Not the most effective solution to the problem
I am a layman, just click on it ^^
Use Spring AOP to uniformly handle exceptions. Of course, the third method is better. Use Spring AOP to intercept exceptions thrown by the service layer, record all unhandled exception logs, and convert all unhandled exceptions into unified custom system exceptions so that the controller layer or Rpc layer can handle these custom exceptions The information is fed back to the front end and displayed on the browser side.
Don’t forget, the real function of using Spring AOP to intercept exceptions is to decouple the exception processing logic from the normal processing logic. So what level do you think the granularity of exceptions is controlled at? This is based on your business logic. For example, the operation of adding, deleting, modifying and checking the database failed? Failed to call external interface? Other abnormal information, etc.
Your company’s methods are irregular and inappropriate. When processing logs, you need to include some processing code in each try-catch block. Sometimes the exception handling code is more than the normal execution code, polluting the normal execution code. The exception handling code is scattered and is very troublesome to modify. Some exceptions cannot be uniformly handled and modified.
If the business method naming in Service is not named according to the pre-defined rules, AOP will not be able to intercept it. In other words, transaction control cannot be loaded. These naming conventions need to be specified in the configuration file.
We all handle AOP exceptions in the controller layer
Exceptions are divided into non-ajax exceptions and ajax exceptions. Because we use jquery, the front-end and back-end are not completely separated. Some front-end data is directly rendered by the back-end
ajax exception: Contain X-Requested-With in the header to determine
Non-ajax exceptions:
Besides ajax exceptions, the way your front desk displays errors to customers must be different, so handle them separately in Interceptor (filter) (aop)
In each method of the service class, it is not said that the whole method is wrapped with try catch. That is too much. Exceptions are divided into things that you cannot control, such as database exceptions, null pointers, etc. These do not need to be caught. In service, they are Based on the exceptions in the business, for example, if the user name is repeated, I will throw a BizException ("Duplicate user name"), where BizException inherits RuntimeException
lz mentioned aop to handle exceptions. I don’t know whether you are in the service layer or the controller layer. Obviously according to my above analysis, it should be done in the controller layer
If this is not the best answer, it would be unreasonable
Are you using spring mvc? Spring MVC has global exception handling. You can search for it. I can't express the details easily on my mobile phone.