一個不知道哪錯的錯!

前言java

本人小菜一枚,這個錯誤最終雖然是找到並解決了,可是如今仍然沒有徹底明白是爲何?問了問其餘的同事也沒具體定位到問題的本質,不過我仍然認爲有記錄的必要性。技術上沒找到這個問題的根源,項目開發上是知道爲何會產生這個問題的!先不說太多,先把這個犯錯和解決錯誤的具體狀況記錄下來,也好爲之後避免這樣的錯誤而積累點小小的經驗!
linux

事源web

此列表是咱們的應用所對應的環境,具體以下所示:spring

軟件環境 開發環境 測試環境 生產環境
操做系統 windows2003
Web服務器

tomcat6數據庫

tomcat6windows

weblogic
數據庫 oracle 10g oracle 10g oracle 10g

 

事情是這樣的,前一段日子咱們作的一個項目,已經上線用戶也一直在用,不過在使用的過程當中出現一個比較奇怪的問題(出問題的地方是一個和文件的上傳下載功能相關的模塊)該功能模塊老是時不時的出現一些問題,可是在開發環境和測試環境上倒是好好的,生產環境用戶一直在用着不能白天停下來查錯,可是必須儘快的將問題解決不然只要用戶一使用對應的功能就會產生錯誤---要上傳的文件上傳失敗。tomcat

我首先想到的緣由多是發佈的問題,咱們專門發佈的同事採用的是增量式的發佈,有些文件生產環境和開發環境可能沒有徹底同步,因而當天晚上咱們從新發布了一版新的應用,而且用Admin用戶登陸測試了一下對應的功能,沒問題了,很高興就回去了!若是問題就這麼容易解決了,個人印象可能就不會這麼深入也沒有記錄的必要性了!次日用戶反饋說仍然有問題(我在客戶現場上班)不對還要繼續的查找,因而當天晚上我和那位發佈應用的同事,開始逐步的查找到底那裏出問題了!服務器

程序出問題是很正常的,也是不可避免的!關鍵是想不通爲何在開發環境下沒問題,在測試環境也沒問題,在生產環境上也不是老是有問題,時而正常時而又不正常!我常說「找到問題產生的緣由等於解決了一半的問題」,在項目開發中或者其餘的狀況下最怕這種不報錯、不拋錯、在開發環境正常在生產環境下時而正常時而又有問題的錯誤了,無從下手,固然主要仍是本身比較菜的緣故!mybatis

如今就大絡的認爲是有因爲系統環境的問題形成了此錯誤,不過排查仍是要的,不能容忍這樣的錯誤存在!咱們仔細的查看了weblogic服務器運行的日誌文件,以期可以找到引發問題的緣由!功夫不負有心人,找到了---在日誌中有一句插入語句沒有執行(咱們的文件上傳是一種多對多的關係,須要往多個表中插入記錄)。因而在本身的電腦上找到對應的程序段,來回檢查了一下,沒有發現有什麼錯誤,讓同事也看了一下,也沒看出有什麼錯,不過在個人Action類中的具體的方法中即用try...catch捕獲錯誤又用throws將錯誤往上拋出交給上一層的程序來處理,同事認爲有問題因而去掉throws部分---從新編譯此文件---從開發的服務器上找到編譯好的文件---拿到生產環境發佈---重啓應用---測試---仍是有問題---查看日誌文件---和上次的狀況同樣依舊不報錯!因而重複上述的操做,只是此次在對應的代碼段中加上了若干條的輸出語句,看看到底走到裏不走了,使用這種方式再細化一下,最後終於找到走到那一句不走出問題了,不過下面就很是奇怪了由於怎麼查也查不出不走的那個一句那裏出問題了(是一段公共的且很是簡單的程序)而後用一樣的方式繼續往那一句的方法中跟進,仍然沒理出頭緒來,看看時間十一點已過沒辦法,明天還得繼續上班明天繼續吧!oracle

次日一上班用戶就問問題解決沒。。。。。。

因而乎,當天晚上咱們計劃繼續搞並且下定決心,找不到問題解決不了問題就不走了!工做的熱情值得嘉獎,不過若是方向錯了越努力錯的就會越遠!下午下班時,咱們提早買上了點吃的,基本上按照昨晚的方式更加細化的又走了幾邊,在十二點的時候頭都昏了!想走又不甘心,當天晚上的風比昨天的更大,只聽見忽忽的拍打着玻璃的巨響,貌似在嘲笑咱們「瞧瞧,這兩個笨蛋這兩天都是幹了些什麼?一個很是簡單的錯誤到如今還沒解決!」我可憐的同事,就這樣陪着也遭了罪,咱們都有些想回去了,不過若是今晚解決不了明晚又得繼續(離週末還有兩天呢!),再查查看若是仍是沒找到問題的所在就回!不過,我左想右想就是想不通,爲何不報錯?爲何不拋錯哪?程序在開發、測試、生產是如出一轍的就環境不一樣,可是開發和測試都正常,生產上又不能調試,好犯難!

起來看看同事玩的啥遊戲,走走動動,從頭至尾再看一遍,就當我從新開發那!此次當看到對應的模型類時忽然間靈光一閃,我終於知道,我錯在哪裏了?

錯誤

咱們的項目文件結構大概以下所示,下面只是一個功能模塊的事例

src.com.ca.agent

                        action//Action類文件包

                        dao//Dao文件類包,dao包下直接放的是咱們手工寫的

                                 mapper//mppper包下的由mybatis自動生成器自動生成的,對應單表的增刪改查都有

                        model //Model文件類包,model包下直接放的是咱們手工寫的,爲了擴展開中發須要的模型類

                                 mybatis//mybatis包下面的由mybatis自動生成器自動生成的,根據數據庫中的表自動生成

                        service//Service文件類包,service包下直接放的是服務的接口類

                                  impl//impl包下直接放的是服務的實現類

最終發現關於文件上傳下載的那個關係表的模型有兩個,model包下面有一個,mybatis包下面也有一個在上面的java類包中用到的全是com.ca.agent.model包下面的,不過在mybatis生成器自動生成的和數據庫交互的映射文件中以及對應的Dao接口類中倒是用的

com.ca.agent.model.mybatis包下面的!固然他兩的屬性和方法徹底同樣,只是在不一樣的包下面而已!問題應該就在這裏了,找到問題下面的事情就比較簡單了,將他們變成統一的應該就能把這個問題完全的解決了!我選擇將com.ca.agent.model包下面的模型類刪掉,程序中用到的所有換成com.ca.agent.model.mybatis包下面的!

從新發布後問題果真完全消失了!這兩天印象頗深,如今還記得很清楚,問題總算搞定,固然更深層的問題還沒解決?

始終沒弄明白,爲何在生產環境下時好時壞?而在開發、測試上則一直沒問題?還有就是爲何不報錯?

下面是部分事例代碼(引發問題的部分代碼,僅示意一下),以作提醒避免下次犯一樣的錯誤!

1:上面的java類包中除了mybatis生成器自動生成的部分,用到的FileAgent類所有引自com.ca.agent.model

package com.ca.agent.dao;
import org.mybatis.spring.support.SqlSessionDaoSupport;
import com.ca.agent.model.FileAgent;

/**
 * @說明:代理人文件管理
 * @author godtrue
 * @修改時間:2014-01-09
 */
public class FileAgentDao extends SqlSessionDaoSupport{
    /*
     * 增長
     */
    public void insert(FileAgent fileAgent){
        this.getSqlSession().insert("com.ca.agent.dao.mapper.FileAgentMapper.insert", fileAgent);
    }

 2:下面是一個mybatis生成器自動生成的一個Dao接口類的部分代碼,類中的FileAgent類引自com.ca.agent.model.mybatis

package com.ca.agent.dao.mapper;

import com.ca.agent.model.mybatis.FileAgent;
public interface FileAgentMapper {
/** * This method was generated by MyBatis Generator. * This method corresponds to the database table SALES.FILE_AGENT * * @mbggenerated Thu Jan 09 18:38:38 CST 2014 */ @Insert({ "insert into FILE_AGENT (AGENT_CODE_ID, FILE_ID, ", "FILE_TYPE_ID, IATA_CODE, ", "OPERATOR, OPERAT_IDENTIFY, ", "LAST_UPDATE_DATE)", "values (#{agentCodeId,jdbcType=DECIMAL}, #{fileId,jdbcType=DECIMAL}, ", "#{fileTypeId,jdbcType=DECIMAL}, #{iataCode,jdbcType=VARCHAR}, ", "#{operator,jdbcType=VARCHAR}, #{operatIdentify,jdbcType=DECIMAL}, ", "#{lastUpdateDate,jdbcType=TIMESTAMP})" }) int insert(FileAgent record);

後話

這個錯誤,如今我只能說和程序運行的環境有關,可是再具體是爲何就不清楚了,有待進一步的查證!不過爲何會出現上面的狀況哪?爲何會出如今一個項目開發中同一張表對應的模型會有兩個如出一轍的狀況哪?這就要說說這個項目管理方面的狀況了,剛開始時咱們這個項目有兩組人共同開發,而且思路都是不同的好比:有一組開發人員歷來不用mybatis自動成的Dao接口文件和對應的數據庫與模型的映射文件,他們認爲裏面的好多代碼都沒有用很是的多餘,而另外的一組人員則是習慣使用這些自動生成的文件!並且命名的習慣也不相同,爲此還專門的開過一次小會制訂了一個項目命名規範的文件!不過有些習慣上的地方仍然沒有徹底的統一,就形成相似這樣的問題的發生!再者就是項目組的成員不是很穩定,最多時開發人員有二十幾個,中途有離職的有調到其餘項目的!這樣代碼的質量很難有很是好的保證,項目管理很是重要,這一塊我尚未具體的涉及,只是看過幾本書,不過從實際的經驗來看仍是能實際的體會到一些東西在的,好比:

1:項目組的人員最好不是拼湊而成的,多少有些默契合做起來才能更加的順暢

2:有些東西最好統一,最好在動手開始作項目的時候就跟你們講清楚,儘可能選擇一種更優的方式,好比:編碼的風格、命名規範、項目的基本業務知識等等

3:就公司而言,我想在項目的開發期間保持項目組的人員儘可能少的變更可能會節約更多的開發成本,除非加入一些很是牛的新成員

固然,對於查錯也有一條比較靈驗的經驗值得分享:當感受有問題愣是查不出來的時候,不妨從頭再來,對於你認爲不可能出錯的地方也去仔仔細細的查查,說不定會有所獲!

相關文章
相關標籤/搜索