在業務層進行復原操作時如何避免復原指令冗餘

來源:互聯網
上載者:User

  眾所周知,資料庫有交易處理(Database Transaction),當一個事務中的操作沒有能全部進行時,之前的操作將復原。

  如果操作都在同一個資料庫上,那可以直接使用資料庫事務進行處理,但是如果跨資料庫操作呢?可以使用JTA。來看看百度百科中JTA的解釋:“JTA,即Java Transaction API,譯為Java事務API。JTA允許應用程式執行分散式交易處理——在兩個或多個網路電腦資源上訪問並且更新資料。”。有興趣的朋友可以搜一下JTA的用法。

  把復原放在業務層有利有弊

  利在於可以不用增加DAO層的代碼,DAO層只單純扮演資料讀寫的角色,操作的粒度很細。細粒度意味著DAO層介面可以擁有更好的複用性。並且,如果不使用JTA,那麼業務層中將不會混入與SQL相關的語句。所有與DB有關的部分都被封裝在DAO層不會泄露到上層。當DB被更換時,只需要更改DAO層的資料介面代碼,而不需要改動業務層代碼。

  弊在於在業務層用代碼實現復原是一件複雜的事情,需要做一步一步的判斷,並且復原指令是累加的。

  為什麼說復原指令是累加的呢?

  假設現在有4個操作(operation1~4),只有當這4個操作都順利進行時才接受,否則就復原之前進行的操作。

  那麼大致的邏輯就是(虛擬碼,假設有四個替換操作,每個替換都成功時才算正確,否則將復原之前的操作):

public boolean rollBackExample(String oldID, Object newOne){                boolean res = true;        Object oldOne = getObject(oldID);                res = Replace1(oldID, newOne);        if(res){            //operation1 success            //now doing operation 2            res = Replace2(oldID, newOne);            if(res){                //operation2 success                //now doing operation 3                res = Replace3(oldID, newOne);                if(res){                    //operation3 success                    //now doing operation 4                    res = Replace4(oldID, newOne);                    if(res){                        return true;                    }else{                        //rollback Replace3 \Replace2 \ Replace1                        Replace3(newOne.getID(), oldOne);                        Replace2(newOne.getID(), oldOne);                        Replace1(newOne.getID(), oldOne);                        return false;                    }                }else{                    //rollback Replace2 \ Replace1                    Replace2(newOne.getID(), oldOne);                    Replace1(newOne.getID(), oldOne);                    return false;                }            }else{                //rollback Replace1                Replace1(newOne.getID(), oldOne);                return false;            }        }else{            return false;        }            }

  可以看到,代碼中進行逐級進行了判斷,並且依據操作進行程度的加深,復原的列表逐漸增多。把復原的操作單獨提出來可以看得更明顯些:

  當第二個操作出錯時,只需復原

//rollback Replace1 Replace1(newOne.getID(), oldOne);

  當第三個操作出錯時,需要復原:

//rollback Replace2 \ Replace1 Replace2(newOne.getID(), oldOne); Replace1(newOne.getID(), oldOne);

  當第四個操作出錯時,需要復原:

//rollback Replace3 \Replace2 \ Replace1 Replace3(newOne.getID(), oldOne); Replace2(newOne.getID(), oldOne); Replace1(newOne.getID(), oldOne);

  假設這個事務有N個操作組成,那麼當進行到第N個操作時出錯,需要進行N-1項復原。而累積的代碼為1 + 2 + …… + N - 1 = N(N-1)/2行代碼,直觀點看就是如果有10項操作,那麼理論上將有9項可能的復原操作,並且在函數中將累計出現45行用於復原的代碼。用於描述復原的代碼的平均重複出現次數達5次。非常拖遝。

  要如何解決這個代碼不優雅的問題呢?

  首先,判斷條件是不可少的,也就是if-else語句無法省略。因為operationj可能是在operationi(j later then i)的基礎上啟動並執行,因此需要一步步判斷以避免出錯。

  其次,不管是哪一步出錯,它進行復原的操作都是與自己所處的執行深度成正相關的。當第k步出錯時,k-1及之前的步驟就需要復原,每一個操作都是如此。這個性質可以在沒有寫break的switch語句中找到影子。當case1執行後,會接著執行case2……以此類推。

  因此我們可以將需要進行的復原操作設計到一個switch-case語句中,虛擬碼如下:

public boolean rollBackExample2(String oldID, Object newOne) {        boolean res = true;        Object oldOne = getObject(oldID);        int phase = 0;        res = Replace1(oldID, newOne);        if (res) {            res = Replace2(oldID, newOne);            if (res) {                res = Replace3(oldID, newOne);                if (res) {                    res = Replace4(oldID, newOne);                    if (res) {                        phase = 4;                    }                } else {                    phase = 3;                }            } else {                phase = 2;            }        } else {            phase = 1;        }        switch (phase) {        case 4:            return true;        case 3:            Replace3(newOne.getID(), oldOne);        case 2:            Replace2(newOne.getID(), oldOne);        case 1:            Replace1(newOne.getID(), oldOne);        default:            return false;        }    }

可以看到,當使用switch-case結構+phase階段判斷時,就不會出現復原指令的代碼冗餘了。 

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.