V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
kikione
V2EX  ›  程序员

什么情况下需要 try catch ? 数据库增删改需要吗

  •  
  •   kikione · 2021-11-20 10:02:06 +08:00 · 2966 次点击
    这是一个创建于 860 天前的主题,其中的信息可能已经有所发展或是发生改变。
    16 条回复    2021-11-22 14:53:43 +08:00
    zjsxwc
        1
    zjsxwc  
       2021-11-20 10:04:06 +08:00
    事务套 crud 中,commit rollback 时肯定要
    markgor
        2
    markgor  
       2021-11-20 10:13:39 +08:00
    1 、偷懶的情況下,如表單驗證,直接 throw 個錯誤,catch 後返回統一的錯誤格式;
    2 、事務下,try.....submit;catch..rollback
    markgor
        3
    markgor  
       2021-11-20 10:15:14 +08:00
    漏了一個,
    3 、函數返回 int 類型時,有些失敗會返回 null ,而我喜歡 throw
    yousabuk
        4
    yousabuk  
       2021-11-20 10:27:31 +08:00 via iPhone
    不 try catch 程序会制造垃圾数据的时候,会崩溃的时候。
    eason1874
        5
    eason1874  
       2021-11-20 10:29:00 +08:00
    不可控的输入,比如解密一段密文,格式错误、密文错误、编码错误,逐个判断太累人

    try catch 一把梭,一次定生死
    darksword21
        6
    darksword21  
       2021-11-20 10:30:36 +08:00 via iPhone   ❤️ 1
    用 go 就不会有这个烦恼了!
    zmxnv123
        7
    zmxnv123  
       2021-11-20 10:40:21 +08:00
    fail safe
    crclz
        8
    crclz  
       2021-11-20 11:01:49 +08:00   ❤️ 4
    异常处理原则如下,对无 gc 语言都适用:

    1. go 和 java 的异常处理思路( exception vs errorcode )没有本质区别

    2. 异常代表了 ExecutionFailure ,代表了 exceptional 。execution failure = exceptional.
    ref: https://docs.microsoft.com/en-us/dotnet/standard/design-guidelines/exception-throwing
    如果这种情况并非 exceptional ,那么请以 errorcode 返回(或者 xxresult )。
    评价:如果你对异常和 errorcode 两种等价的形式的应用场景不明白,那么这一条可以指导你。

    3. 吞调异常代表了未知到已知的转换。(未知:exceptional 。吞掉:catch 而不 rethrow )
    解释:catch 而不 rethrow 代表了:对于被调函数,这种情况是 exceptional 的,但是对于调用者来说不是。

    4. 不忽略未知异常。
    翻译:不 catch Exception ,而是 catch SomeException 。
    理由:未知异常代表着潜在的 bug 。
    例外:根异常捕获器需要 catch Exception ,但是如果是未知的异常,需要通过报警系统通知开发者。

    5. catch 、rethrow 、打印日志是正交的概念。
    示例 1:rethrow+打日志代表了遇到了 exceptional 的情况,并且想要记录一些诊断信息。
    示例 2:只 catch 不 rethrow+打日志代表了遇到了意料之中的错误,并且想要记录一些诊断信息。


    对于楼主的问题,以下是具体回答:

    在我们公司,数据库驱动层会打日志(和 metrics ),以跟踪具体库的成功率指标,提升可监控性。
    开发者如果想要获得面向业务的监控指标,那么需要自己 catch+打日志(+metrics )。(因为一个业务操作可能涉及多个数据源、多次查询)
    那么,catch+打日志后是返回 errorcode 还是 rethrow ?请参考 1-5.
    cmdOptionKana
        9
    cmdOptionKana  
       2021-11-20 14:12:42 +08:00
    @darksword21 确实,Go 的优点是 error 是非常 verbose 的,并且编程规范上也强烈倡议大家每个 error 都要认真处理。

    缺点还是“非常 verbose”,导致想偷懒的时候不容易偷懒。

    总之一件事情有利有弊,综合看待,很多人只说 Go 的 error 太罗嗦,却忽视了 verbose 的好处。
    Jooooooooo
        10
    Jooooooooo  
       2021-11-20 15:49:22 +08:00
    @darksword21 这不是语言问题, 是逻辑问题. 意思在于, 如果和数据库交互发生诸如超时异常, 那后续逻辑应该处理的问题.

    举个例子, 用户访问网站, 需要判断是否用户是新用户而展示对应的新人模块, 但判断用户是否新用户的模块超时了, 此时无法得知用户是不是真的新用户.

    那么后续应该:

    1. 直接返回错误页面展示请重试,

    2. 还是把用户直接当新用户展示新用户的模块,

    3.还是把用户当做老用户展示对应的模块.
    ch2
        11
    ch2  
       2021-11-20 20:06:13 +08:00
    经验证明异常有一定概率会出现,而且你不希望该异常没有处理而造成无法忍受后果,于是显式指定处理方式
    如果错误出现概率非常低(可能性跟进程申请不到内存差不多),或者出现错误也无关紧要,就不用 catch
    xuanbg
        12
    xuanbg  
       2021-11-21 07:50:34 +08:00
    只有在 catch 里面你能有办法使业务流程继续下去的时候,才有必要 try 。要是发生异常的时候你除了打印个错误日志外就束手无策的话,还是抛出来统一处理(打印日志)就完了。
    pythonee
        13
    pythonee  
       2021-11-22 11:33:58 +08:00
    @darksword21 好奇为什么 go 没有此烦恼呀
    puzzle9
        14
    puzzle9  
       2021-11-22 14:39:57 +08:00
    @pythonee 使用 go 每一步都要进行判断
    puzzle9
        15
    puzzle9  
       2021-11-22 14:40:41 +08:00
    就是这部分没把握运行只能是成功的时候
    pythonee
        16
    pythonee  
       2021-11-22 14:53:43 +08:00
    @crclz 感觉这是对“异常”说的最清楚的一次
    作为开发者,是要好好考虑什么是 exception 、什么是 failure 、什么是 error 了
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   5738 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 26ms · UTC 06:24 · PVG 14:24 · LAX 23:24 · JFK 02:24
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.