在持久化数据的读写操作中经常要涉及到 数据库与缓存 的操作,同一时候因为业务须要经常要对多表进行事务操作。基于结构层次化设计的思想我们经常须要对这一系列操作进行分层设计。

各层的主要职责。以及发生异常怎样处理。是向上继续抛出,还是在该层对异常做转换等处理,以及事务中发生异常时缓存的处理等须要一些思考。

以个人的经验为例:
经常将持久化操作分为3层:dao层,manager层,service层
当中
dao层:直接进行数据库读写操作。


发生异常时,向上抛,调用方能够依据捕获的异常信息。找到db放生错误的原因(sql语法错误 还是 反复插入同一主键等)

public List<Something> queryList(SomethingQuery SomethingQuery) throws DAOException;

manager层:改成将配合缓存进行数据库的读写操作。
我的做法

insert:
     insertDB(something)    //直接操作db
query:
     something = getSomethingFromCache   //首先读缓存,不存在时读db
     if(something == NULL) {
         something = getSomethingFromDB
         putSomethingToDB(something)
     }
     return something
update:
    updateDB(something)    //更新db。同一时候失效缓存中 脏数据
    invalidCache(something)
delete:
     deleteDB(something)   //删除db中数据。同一时候失效缓存中 脏数据
     invalidCache(something)

该层发生异常时,对外抛出,不曾不作处理。我之前的做法,在该层多异常作处理。如发生异常时 我就返回null, 这种弊端在于 调用方对null无法做进一步的区分(是发生异常 还是 db与缓存中 均不存在 导致返回null),从而使容错性能下降,比如假设能是异常导致的,则能够进行多次尝试。而当数据不存在时。就须要马上返回作处理了。毕竟manager层相对来说层级较低,说要向上层调用方提供尽可能多的信息,方便做容错等错里。

service层:在该层经常会依据业务的须要做多表的事务操作。

update:
            doInTransaction(TransactionStatus status) {
                try {
                    Long tableId1 = table1.insert(something1);
                    Long tableId2 = table2.insert(something2);
                } catch (Exception e) {
                    status.setRollbackOnly();
                }
            }

该层发生异常时,经常会依据业务需求作转换,比如对于查询失败操作,能够将失败的详细信息一并返回调用方,便于问题排查。

queryResult.isSuccess = false;

queryResult.msg = “db error”;
queryResult.msg = “不存在”;