從一次故障解決想到的

realkid4發表於2011-02-16

 

近日進行開發環境例行檢查,發現資料庫中某張表多出一個欄位。欄位命名為過去一個已經被改名的欄位名稱,型別為number(9,2)(原來的型別為number(13),沒有comments資訊。筆者心想:看來又有開發人員開啟了JPA自動同步資料庫開關了。

 

ORM框架技術是目前解決關聯式資料庫模型和實體物件模型阻抗不一致的主流手段。透過配置檔案或者配置標籤,實現將實體類與關係資料表的對映。在應用程式碼中,只需要進行實體型別的操作,ORM框架會自動生成SQL語句,進行資料的持久化操作。

 

目前,業界流行的ORM框架有很多。最常見的可能就是Hibernateibatis,此外還有EJB3的永續性解決方案JPA。筆者遇到的開發系統就是建立在JPA解決方案下。

 

在一些框架中,提供了自動ddl的功能。也就是說,在應用啟動的時候,會自動檢查當前的實體物件對映關係是否和資料庫表結構匹配。如果不匹配的話,會自動的生成ddl語句,並且在資料庫上執行,同步資料庫結構。很多應用中,這個開關是預設開啟的。在筆者開發的系統中,是不允許使用這個功能的。

 

筆者遇到的問題就在於此。欄位更名的變更已經很長時間,並且反覆強調過自動同步開關的關閉。再次出現ddl同步的原因只有出現開發人員使用了非最新的程式碼實體型別,並且開啟了自動同步功能開關。

 

不管如何,先把這個開發人員定位出再說吧。只能透過all_objects檢視的last_ddl_time確定出大致的同步時間,嘗試從Redo Log中獲取對應的資訊。在這個過程中,使用了logminer嘗試獲取到執行ddl操作時保留的會話資訊。

 

SQL> alter system switch logfile;

 

System altered

 

SQL> select name from v$archived_log where first_timeto_date('2011-2-14 15:53:02','YYYY-MM-DD HH24:MI:SS');

 

NAME

---------------------

NBSDEVSTY

/nbsarch/NBSDEV/1_437_729298248.arc

 

SQL> select name from v$archived_log where first_timeto_date('2011-2-14 15:53:02','YYYY-MM-DD HH24:MI:SS');

 

NAME

--------------------

NBSDEVSTY

/nbsarch/NBSDEV/1_437_729298248.arc

 

SQL> exec dbms_logmnr.add_logfile('/nbsarch/NBSDEV/1_437_729298248.arc',dbms_logmnr.NEW);

 

PL/SQL procedure successfully completed

 

SQL> exec dbms_logmnr.start_logmnr(Options => dbms_logmnr.DICT_FROM_ONLINE_CATALOG);

 

PL/SQL procedure successfully completed

 

 

結果是令人沮喪的,分析日誌的結果雖然可以找到執行的ddl語句。但是由於使用者登入是使用前端JDBC進行連線,所以Session_Info資訊返回的都是UNKNOWN

 

 

SQL> select scn,session_info, timestamp,sql_redo from v$logmnr_contents where sql_redo like '%STK_STOCKHISTORY%';

 

       SCN SESSION_INFO   TIMESTAMP          SQL_REDO

----------------------------------------------------------------------

  96907227 UNKNOWN        2011/2/14 15:53:02 analyze table NBS.STK_STOCKHISTORY

                                                   estimate statistics;

  96907255 UNKNOWN        2011/2/14 15:53:02

                                             alter table STK_STOCKHISTORY

                                                    add REASON_SEQ number(19,2);

  96907265 UNKNOWN        2011/2/14 15:53:02

                                             alter table STK_STOCKHISTORY

                                                 add SERIESCODE_SEQ number(19,2);

 

 

 

在沒有其他更好辦法的情況下,最後筆者只能使用笨辦法:依次找每個開發人員環境進行確認。最後還是定位到了一位開發人員身上,發現的確是使用的非配置管理的舊程式碼,並且開啟著自動同步開關。故障解除

 

雖然這個問題沒有使用什麼高明的技術進行解決,最後等於也是用笨辦法搞定。但是思考下,還有有些想法。

 

關於ORM自動同步功能

 

首先,筆者承認ORM自動同步功能是一個非常有意義的功能。很長時間裡,我們的開發設計人員精力都是集中資料庫ER關係上。而我們進行的物件導向分析設計,關注的重點是在類的職責劃分以及類之間的互動上。過多的關注資料庫會造成這種脫節逐步深化。設計實體類,之後使用ORM自動同步生成資料庫結構,也就自動的消除了這種現有資料表後又實體類的情況。

 

但是,目前的ORM自動同步,還存在一些缺陷和不足。資料庫設計絕不僅僅是資料表和列表為代表的邏輯設計。在一些中大型系統中,物理設計、SCHEMA選擇尤為重要。這不僅僅是關係開發規範的落實,而且關係到系統未來效能合理性等。

 

有的朋友可能會提出先建立表,之後由資料庫規劃人員整理結構。這樣做的成本其實是更高的,因為沒有一個統一的DB設計思路。而且在遇到發起變更的時候,前後不一致的問題會很大。

 

第三,ORM自動同步還存在一些需要逐步完善的內容。註釋、主鍵、索引等資料庫特定的物件,還是鮮有自動生成支援。後補完善的工作量也是很巨大的。

 

最後,自動ORM同步時需要專門的工具進行支援。一個簡單的道理,如果我們在本地新增一個試驗性的欄位,自動同步在開發環境下,相當於把未確認的程式碼遷入。這樣是一種絕對不允許的行為!所以,通常使用這種方法的團隊,都是使用本地小型資料庫進行支援,如SQLite。在確認程式碼結構後,將ddl指令碼和實體類指令碼一起同步到配置管理和開發環境下。

 

 

結論:採用一項技術,特別是開發流程技術,要進行綜合的考量才能確定。主要是人力、制度規範、支援工具和專案性質幾個因素確定。一定的開發團隊水平,適合合理的制度,支援技術的工具軟體以及具體專案屬性,才能採用最適當的技術策略。技術方案沒有好壞,只有是否適當。

 

 

個人觀點,僅供指正。

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/17203031/viewspace-687374/,如需轉載,請註明出處,否則將追究法律責任。

相關文章