当前位置: 首页 > 编程日记 > 正文

某大型银行深化系统之二十:异常规范

传送门 ☞ 轮子的专栏 ☞ 转载请注明 ☞ http://blog.csdn.net/leverage_1229

1异常抛出与捕捉规则

1.1任何抛出异常的方法必须先声明异常

{// Constructorpublic MyClass( String name ) throws NullPointerException, llegalArgumentException {...}
}

1.2异常声明后,调用异常对象的构造器抛出异常

public MyClass( String name ) throws NullPointerException, IllegalArgumentException {if ( name == null )throw new NullPointerException( );if ( name.length == 0 )throw new IllegalArgumentException( );...
}
Java异常都从Throwable类继承而来。

1.3用try,catch声明捕捉异常

try {MyClass newobj = new MyClass( name );
} catch ( NullPointerException e ) {//  Do something about it
} catch ( IllegalArgumentException e ) {//  Do something about it
}
当try中的语句产生异常时,在异常处理函数捕捉了该异常而又没有重新抛出异常时,则在执行完处理函数后,将跳出发生异常的try块,接着执行下面的语句。当try中的语句产生异常时,在异常处理函数捕捉了该异常而又重新抛出异常时,则将把异常抛出到上一层,发生异常的语句之后的代码将不执行。如果没处理相应异常的处理函数,将把异常抛出到上一层,发生异常的语句之后的代码将不执行。如果想捕捉所有异常,只要捕捉Exception异常就行。如果某段代码不管是否发生异常都要执行,那可把它放入finally块中,以finally进行清理。

2取得异常信息的几个常用方法

String getMessage()、getLocalizedMessage 、toString()取得异常对象中的信息。
void printStackTrace()、Throwable fillStackTrace()。printStackTrace打印出Throwable和其call stack trace;FillStackTrace则在调用点设立新的stack trace信息。
RuntimeException异常。RuntimeException及其子类所代表的异常我们在程序中不用进行捕捉,如果发生此类异常,Java会自动抛出相应的异常对象。

3继承中异常规则

3.1构造函数中的异常规则

某个derived class构造函数的“异常规格接口”可以比其所调用的父类的构造函数的异常规格接口宽,但决不能变窄。
        derived class的构造函数必须在自己的异常规格中声明所有base class构造函数的异常规格中所声明的异常。
        在derived class的构造函数的异常规格中还可以声明新的异常,即声明在base class构造函数的异常规格中没有声明的异常。

3.2非构造函数的异常规则

某个函数的“异常规格接口”在继承和重载中可以变窄,但决不能变宽。要覆写base class的函数时,如果被覆写函数(base class中的函数)的异常规格中声明了异常,那么覆写函数(derived class中覆写了base class中的函数的那个函数)的异常规格中可以声明:
与被覆写函数完全相同的异常;
被覆写函数异常规格中的部分异常或其子类异常;
不声明异常规格。

3.3.产生对象的异常规则

在产生一个对象时,捕捉的是产生对象时所调用的构造函数中所声明的异常。

3.4.函数调用时的异常规则

当把一个对象向上转型为它的base class时,并通过转型后的reference进行函数调用时,我们要捕捉的是其base class的异常声明。

当用对象的原始类型来调用函数时,只需捕捉所调用的覆写函数的异常。

4异常分类

4.1.Checked Exception

Checked Exception是指那些需要程序显式的处理(捕获或者继续抛出)的异常。在项目中Checked Exception主要可以分为以下三种:

4.1.1BizException

项目自己定义的业务异常,BizException下继承了若干个子异常。也就是说BizException是所有项目自定义异常的根类。

4.1.2RollbackableBizException

项目自己定义的业务异常,是BizException的子类。

4.1.3Other Checked Exception

其他非本项目定义的Checked Exception类异常

4.2.Unchecked Exception

Unchecked Exception是指那些不需要程序进行显式处理(捕获或继续抛出)的异常,如果程序需要处理这类异常则其处理方式和Checked Exception一样。在项目中Unchecked Exception 主要可以分为以下两类:

4.2.1DataAccessException

这类异常主要是Spring框架定义的数据访问类异常,其具体类型根据数据库的不同和数据库所产生的错误的不同而不同。该类异常描述了数据库访问过程中所产生的错误。其下还有若干个子类异常,下面列出了这些异常:
CleanupFailureDataAccessException:数据访问操作之后无法正常执行清除工作,比如JDBC访问之后无法正常关闭Connection。
ConcurrencyFailureException:并发时可能出现此类异常,其下有若干子类异常来标识乐观锁和获取锁失败这两类异常信息。
OptimisticLockingFailureException:在违反了乐观锁机制的情况下会抛此异常
PessimisticLockingFailureException:违反悲观锁机制的情况下会抛出此异常。此异常是由SQLException转换过来的。
CannotAcquireLockException:无法获取锁异常,一般在数据更新时获取锁失败时抛出
DeadlockLoserDataAccessException:当一个并发进程进入死锁链,通常需要抛出异常并回滚该进程产生的事务 。
DataAccessResourceFailureException:当访问某个资源失败时抛出此类异常,比如无法用JDBC与数据库之间建立连接。其下有如下几个子类
CannotCreateRecordException:由于连接器(Connector)内部原因造成创建CC I(Common Client Interface)记录失败时抛出此异常。
CannotGetCciConnectionException:严重异常,无法通过CCI(Common Client Interface)连接EIS(企业信息系统)抛出此异常。
CannotGetJdbcConnectionException:严重异常,无法通过JDBC连接到关系数据库(RDBMS)。
DataIntegrityViolationException:当向数据库插入一条数据或修改数据库中的数据时违反了数据库的完整性约束时抛出此异常。
DataRetrievalFailureException:当无法获取预想的数据时抛出此异常。其下有若干子异常。
IncorrectResultSizeDataAccessException:当获取的数据数量不是预想的数量的时候抛出此异常,比如预想获取到1条数据,但是获得了0条或者多条数据时抛出此异常
LobRetrievalFailureException:LOB无法被获取的时候抛出此类异常
ObjectRetrievalFailureException:通过映射对象(Object)的标识符来获取映射对象失败。
HibernateObjectRetrievalFailureException:将Hibernate和 UnresolvableObjectException, ObjectNotFoundException, ObjectDeletedException和WrongClassException转换为此异常。
InvalidDataAccessApiUsageException:当错误的使用了API的时候抛出此异常
InvalidDataAccessResourceUsageException:当恰当的访问数据时出现此异常,比如,SQL语法不正确。其下有多个子异常类。
BadSqlGrammarException:定义的SQL语句是非法的,有语法错误的时候抛出此异常,一般情况下都是由一个SQLException引起的。
CciOperationNotSupportedException:当连接器(Connector)不支持特定的CCI(Common Client Interface)操作的时候抛出此异常
HibernateQueryException:当HQL(Hibernate的数据库查询语句)语句出现错误时抛出此异常。
IncorrectUpdateSemanticsDataAccessException:当更新数据库数据时出现非预想的结果,这个时候数据库的事务还没有回滚。比如预想修改1条数据,但实际修改了3条数据。
InvalidResultSetAccessException:访问结果集不合法,比如非法的字段名等等。
RecordTypeNotSupportedException:当由于连接器(Connector)不支持预想的CCI记录(record)类型而造成创建一个CCI 记录(record)的失败的时候抛出此异常。
TypeMismatchDataAccessException:当Java类型与数据库(RDBMS)的类型不匹配的时候出现此异常。
UncategorizedDataAccessException:无法分类的异常,其下有若干子异常
HibernateJdbcException:此异常是对Hibernate的JDBC异常的简单包装。
HibernateSystemException:当发生其他一些Hibernate错误是否抛出此异常,这些错误与org.springframework.dao中所定义的异常无法匹配
SQLWarningException、UncategorizedSQLException:无法分类的SQLException

4.2.2Other RuntimeException

其他类型的RuntimeException,例如:NullPointException等。

5异常使用原则

使用异常主要是为了报告系统运行中出现的非正常情况。目前异常使用的方法有两种。一种是使用不同的异常类来表示不同的异常,这些异常类的类名就表达了系统所处的非正常状态。另一种是系统中出现的所有异常都用很少的几个异常类来表示,通过这些异常类中Message来表达具体的异常信息。项目主要使用的的是后一种方法。但在某些主要的子系统或与外系统交互时也会采用一些第一种方法。
        Message主要由两部分组成Key和Param[],其中key的命名规则为:级别(1位)_模块名(可选)_逻辑名,其中级别主要分为Warn(W)和Error(E)两个级别。模块名:指应用功能的名称。逻辑名:从某种角度上来说可以理解为异常的编码。Param[]是具体的异常信息的参数。其具体使用方法如下,首先应用程序从异常中获取Message,然后从Message中获取key值,根据key值从resource文件中获得异常描述信息,将Param[]通过填空形式放入获得异常描述信息中形成一个完整的异常描述信息。

5.1Checked Exception

根据是否需要事务作RollBack操作而使用不同类型的异常。

5.1.1RollbackableBizException

需要事务RollBack则抛出RollbackableBizException。

5.1.2BizException

如果不需要事务作RollBack操作则抛出BizException。

5.1.3Other Checked Exception

在项目的应用程序中只负责处理这类异常,不产生或使用这类异常。

5.2Unchecked Exception

鼓励应用程序重用一些通用的UncheckedException异常,如IllegalArgumentsException, NullPointException等。

5.2.1DataAccessException

大多数情况下这类异常应用程序不用关心,特别是DAO类的对象不用关心这类异常。它是Spring框架所抛出的数据库访问的异常。

5.2.2Other RuntimeException

6异常处理原则

异常处理需要遵循几点基础原则:
第一,能处理则进行处理和关心的异常,不能处理或不关心的异常则继续抛出。决不允许出现捕获异常但又不做任何处理或抛出操作,这样会丢失异常信息。
第二,异常抛出源需要在抛出异常之前将异常写入日志中。以备进行检查。
应用程序所处层次的不同其对异常的处理也有所差别。下面列出了每个层次的应用程序在处理异常的一些原则。
        下图是项目中异常使用的一个图释:


6.1web layer(展示层)

该层将从Business layer获取的异常根据异常所传递的消息的不同来区分当前异常是否可恢复。这里指的可恢复是指当出现异常后操作人员可以通过改变输入来解决出现的异常。按照可恢复性的不同,该层应用对异常的处理也有所区分。具体操作过程中该层根据获取异常Message来确定处理的方式。如果Message的级别是Warn则需要将异常信息显示到操作员录入页面并保留上次录入信息,如果Message级别是Error则需要将信息转向专门的异常显示页面显示异常信息。

6.1.1可恢复异常

这类异常处理的时候应将异常信息显示在用户输入的页面并保留相关的输入信息,以便让操作员通过修改输入来纠正异常。

6.1.2不可恢复异常

该类异常由于无法通过简单的改变操作员的输入来进行纠正,因此这类异常也比较严重。需要将该类异常的信息转发到专门的异常信息显示页面上。

6.2Business layer(业务层)

该层可以分为UCC(用例控制)层和Service(服务)层。对于该层的异常处理也应该分成两部分来看待。

6.2.1UCC Layer(UCC层)

该层除了负责处理本层所产生的异常外还要负责Service层所抛的所有异常。对于其根据获取的异常的类型来做相应的处理。一般情况下对于从Service层获取的异常都是再次抛出,但在抛出前需要控制事务是否需要RollBack。如果获取的错误是RollbackableException和UnChecked Exception则需要事务RollBack操作,如果是BizException则需要根据具体业务用例来确定是否需要事务RollBack,但原则是在抛出异常之前如果已经发生了数据库的Create、Update、delete等修改类型的操作则需要进行RollBack操作,否则则不需要RollBack。UCC层可以处理除了Other Checked Exception以外的所有异常类型。

6.2.2Service Layer(服务层)

Service层来除了负责处理自身处理过程中所产生的异常还要负责Integration Layer所抛出的异常的处理。一般情况下不需要处理Unchecked Exception,但如果业务需要也可以捕获Unchecked Exception并作相应的处理。Service所能够处理的异常类型是本文所提到的所有类型的异常。

6.3Integration layer(整合层)

整合层根据数据源类型的不同异常的处理原则也不同。

6.3.1数据库

当数据源为数据库的时候,应用程序不需要捕捉数据库的异常或者Hibernate产生的异常(这些工作都有Spring框架完成)。在该层处理过程中如果出现异常则此类异常的严重等级都比较高,都需要做事务的RollBack操作。因此在这里出现异常都使用DataAccessException异常,当然具体异常类型可以为DataAccessException下的一个字类型。

6.3.2其他外部系统

数据源为其他外部系统的时候,该层对外部系统所产生的异常进行相应的封装。封装建议按照用异常类型来区分是什么异常的形式进行。这里抛出的异常一般都是特定的异常不是BizException类型的。Service在接收到该层抛出的异常以后根据异常的类型装换成相应Message放入BizException中重新抛出或者自己消化,但根据需要的不同也可以将异常直接重新抛出。

转载于:https://www.cnblogs.com/innosight/archive/2013/05/27/3271244.html

相关文章:

女朋友的Mysql练习题

2019独角兽企业重金招聘Python工程师标准>>> 一、设有一数据库,包括四个表:学生表(Student)、课程表(Course)、成绩表(Score)以及教师信息表(Teacher&#xf…

中国电子学会图形化四级编程题:解密

「青少年编程竞赛交流群」已成立(适合6至18周岁的青少年),公众号后台回复【Scratch】或【Python】,即可进入。如果加入了之前的社群不需要重复加入。 我们将有关编程题目的教学视频已经发布到抖音号21252972100,小马老…

python函数模块概念_python中模块和包的概念

1.模块一个.py文件就是一个模块。这个文件的名字是:模块名.py。由此可见在python中,文件名和模块名的差别只是有没有后缀。有后缀是文件名,没有后缀是模块名。每个文件(每个模块)都是一个独立的名称空间,也就是说可以在两个(多个)…

linux-glibc内存管理小结2(内存相关系统调用的实现)

在上一节ptmalloc源码分析中我们提到dlmalloc向系统申请内存的方式有两种, 对应Linux系统下分别是sbrk()与mmap()系统调用. 本节我们就来看下brk()/sbrk()与mmap()/munmap()的实现, 作为切入点来一窥内核内存管理的特点. 在正文开始之前我们先大致描述一下内核内存管理的模型. …

【组队学习】【30期】7. CV中的Transformer

CV中的Transformer 航路开辟者:安晟领航员:尚育鹏航海士:安晟、袁明坤、闫永强 基本信息 开源内容:https://github.com/datawhalechina/dive-into-cv-pytorch [第六章]内容属性:打磨课程内容说明:17年在…

天堂Lineage(單機版)從零開始架設教學

此篇文章 內容大部份連結 已失效, 我已另外寫一篇更快速安裝的文章。 前言: 網路遊戲天堂在數年前,被日本人分析封包的方式。模擬出Lineage server端的行為。 不像天堂II,及RO是由內部洩漏出Server端程式。也由於天堂Server的熱門以至於私服人…

python爬虫天气实例scrapy_python爬虫之利用scrapy框架抓取新浪天气数据

scrapy中文官方文档:点击打开链接Scrapy是Python开发的一个快速、高层次的屏幕抓取和web抓取框架,用于抓取web站点并从页面中提取结构化的数据。Scrapy用途广泛,可以用于数据挖掘、监测和自动化测试,Scrapy吸引人的地方在于它是一…

中国电子学会图形化四级编程题:绘制雪花

「青少年编程竞赛交流群」已成立(适合6至18周岁的青少年),公众号后台回复【Scratch】或【Python】,即可进入。如果加入了之前的社群不需要重复加入。 我们将有关编程题目的教学视频已经发布到抖音号21252972100,小马老…

C++ Primer 读书笔记 - 第十三章

1. Initialization和Assignment不一样。其中Initialization包括direct-initialization (如A a(...))和copy-initialization (如 A a b;) 注意A a b为copy-initialization, 而A a; A b; a b;为Assignment。 2. We cannot copy objects of the IO types, so we can…

Linux-LNMP(静态元素不记录日志和过期时间,防盗链,解析php,代理,支持ssl)

Linux-LNMP-Nginx配置二 静态文件不记录日志和过期时间Nginx防盗链Nginx访问控制Nginx解析php相关配置Nginx代理Nginx负载均衡SSL原理生成SSL密钥对Nginx配置SSL静态文件不记录日志和过期时间在Nginx服务器的虚拟主机配置文件(/usr/local/nginx/conf/vhost/norecord.conf)中定义…

mysql数据库优化命令_MySQL数据库优化总结

一个:MySQL标准数据库优化注意事项1.数据库设计(表设计合理)三范式(规范的模式)三范式包含:第一范式:1NF是对属性的原子性的约束。要求属性具有原子性,不可再分解。(仅仅要是关系型数据库都满足)第二范式:2NF是记录的唯…

C++ 卸载程序

目的:用C写一个自己的卸载程序来完成程序的卸载工作,同时运行后要删除卸载程序本身,并删除卸载程序所在的文件夹。 注:在程序退出的时候写上 自己的卸载代码。 // FileName: Uninstall.h #pragma onceclass CUninstall { private:…

《火星救援VR》原班人马打造全新AR游戏,让可爱小飞龙伴随你左右

曾开发了《火星救援》的VR团队即将发布AR游戏《Follow Me Dragon》,让可爱小飞龙“融入”真实世界。 开发商The Virtual Reality Company曾经打造过风靡一时的《火星救援》VR游戏。今日,他们刚刚发布了一款名为《Follow me Dragon》的AR游戏。 目前&…

【组队学习】【30期】时间序列分析

时间序列分析 航路开辟者:李岳昆、易远哲领航员:王洲烽航海士:李岳昆、易远哲 基本信息 开源内容:https://github.com/datawhalechina/team-learning-data-mining/tree/master/TimeSeries内容属性:打磨课程内容说明…

mysql二进制日志管理_MYSQL二进制日志管理脚本

MYSQL二进制日志管理脚本脚本原理是每小时对进行flush生成新的二进制日志,将二进制日志备份至NFS,并压缩存放:#!/bin/bash#Purpose:管理二进制日志,每小时刷新二进制日志,并将日志复制到nfs服务器上,方便以…

iPhone App开发实战手册学习笔记(5)之IOS常用机制

1 前言 在IOS开发中,相信大家一定听说过委托,数据源,target,action等等,今天我们就来简单的学习一下这些内容。 2 详述 2.1 委托和数据源 大家是否曾经有不知道如何去执行一项任务的时候?或许是修理一台洗碗…

Datawhale组队学习周报(第035周)

希望开设的开源内容 目前Datawhale的开源内容分为两种:第一种是已经囊括在我们的学习路线图内的Datawhale精品课,第二种是暂未囊括在我们的学习路线图内的Datawhale打磨课。我们根据您的投票来确定精品课程的排期,打磨课程一旦完成&#xff…

【Project Euler】530 GCD of Divisors 莫比乌斯反演

【题目】GCD of Divisors 【题意】给定f(n)Σd|n gcd(d,n/d)的前缀和F(n),n10^15。 【算法】莫比乌斯反演 【题解】参考:任之洲数论函数.pdf 这个范围显然杜教筛也是做不了的,而且考虑直接化简f(n)也遇到了困难,所以考虑将前缀和的…

php mysql 星级评分_jQuery+PHP实现星级评分

本例实现的效果:过渡动画显示评分操作。及时更新平均得分和用户所评的分数。后台限制用户重复评分操作,并在前端及时显示。XHTMLHTML结构分为用于显示灰星星div#big_rate、亮星星div#big_rate_up、分数span#s及span#g和提示信息div#my_rate。CSS.rate{wi…

Xt800、DEFY自带号码归属地更新包,更新至2013.4【数据总数278360条】

总结了http://bbs.gfan.com/forum.php?modviewthread&tid5603346&extrapage%3D1&page1和http://bbs.mfunz.com/thread-706813-1-1.html,经测试在我的XT800上可用,可以把其他的第三方来电软件通通删掉了。 特点:能够显示运营商&a…

中国电子学会图形化四级编程题:程序优化

「青少年编程竞赛交流群」已成立(适合6至18周岁的青少年),公众号后台回复【Scratch】或【Python】,即可进入。如果加入了之前的社群不需要重复加入。 我们将有关编程题目的教学视频已经发布到抖音号21252972100,小马老…

当代艺术遇上虚拟现实:幻境视界打造基业VR美术馆

VR展览也许并不少,但专业的艺术展却难得一见。幻境世界周志强希望能借助VR技术,实现“一地办展、全球同展、永不闭馆”,更好地传播当代艺术。 从米开朗琪罗到库尔贝,再到雷诺阿,大师们不断找到新的艺术语言来阐释人体…

python二叉搜索树建立_700. 二叉搜索树的搜索(Python)

题目难度:★☆☆☆☆类型:二叉树给定二叉搜索树(BST)的根节点和一个值。 你需要在BST中找到节点值等于给定值的节点。 返回以该节点为根的子树。 如果节点不存在,则返回 NULL。例如,给定二叉搜索树:4/ \2 7/ \1 3和值: 2你应该返回…

CF484E Sign on Fence

题意 给定一个长度为n的数列,有m次询问,询问形如l r k 要你在区间[l,r]内选一个长度为k的区间,求区间最小数的最大值 Sol 二分答案 怎么判定,每种数字开一棵线段树 某个位置上的数大于等于它为1 那么就是求区间最大的1的序列长度大…

【组队学习】【30期】吃瓜教程——西瓜书+南瓜书

吃瓜教程——西瓜书南瓜书 航路开辟者:谢文睿、秦州领航员:邱振波航海士:谢文睿、秦州 基本信息 开源内容:https://github.com/datawhalechina/pumpkin-bookB 站视频:https://www.bilibili.com/video/BV1Mh411e7VU内…

如何破解压缩文件密码-省时省力的方法

压缩文件破解工具下载地址:http://www.cnblogs.com/spring_wang/archive/2013/06/14/3135163.html 应该很多人都碰到过RAR加密、解密的问题吧。简单给大家介绍下如何用工具来破解RAR密码!我们所利用的工具,就是“ARPR”、相信有些人肯定知道。…

学完javase和mysql_Java基础学完接下来应该学什么呢?

谢谢邀请!Java基础部分涵盖了类、对象、属性和方法四大概念,以及封装、继承、多态的理解及使用。Java基础部分是Java学习过程中相对来说比较难的部分,Java语言属于开头难,之后越学越简单的语言。基础部分要清晰Java面向对象的开发…

Linux文件分割与合并:splitcat(转载)

转自:http://os.51cto.com/art/201104/255359.htm Linux下文件分割可以通过split命令来实现,而用cat进行文件合并。而分割可以指定按行数分割和安大小分割两种模式。Linux下文件合并可以通过cat命令来实现,非常简单。 在Linux下用split进行文…

【组队学习】【30期】李宏毅机器学习(含深度学习)

李宏毅机器学习(含深度学习) 航路开辟者:王茂霖、陈安东,刘峥嵘,李玲领航员:初晓宇航海士:王茂霖 基本信息 开源内容:https://github.com/datawhalechina/leeml-notes开源内容&am…

mac下用Dosbox搭建dos下的汇编环境

安装Dosbox,下载地址 pan.baidu.com/s/1qZfgGc0 安装汇编编译器,下载masm pan.baidu.com/s/1c4k5fCc,在个人目录下新建 ~/Dosbox目录,把masm拷贝到Dosbox目录中 设置Dosbox autoexec, 编辑~/Library/Preferences/DOSBox\ 0.74\ …