步驟清單:
在上一議題中,我們演示了一個最簡單的數據同步情景。由此,我們有幾點總結:
MobiLink 由服務器端(dbmlsrv9)和客戶端(dbmlsync)組成。服務器端與數據中心連接,客戶端與遠程數據庫連接。其中,數據中心可以是任何符合 ODBC標准的數據源,例如Oracle、IBM DB2、MS SQLServer與Sybase ASE等。
MobiLink在同步的過程中首先將遠程數據庫的數據上載,接著將數據中心的數據下載,以此完成一次同步。
在非常簡單的情況下,不需要編寫任何腳本。
但是情況總是會變化的。我們可能有特殊要求。例如,我們只需要某一個部門的數據,我們不想把所有的更改都上傳到服務器上……那麼,通過什麼來指揮MobiLink上載或者下發哪些數據呢?就通過在統一服務器端編寫的MobiLink的事件和事件中的腳本來控制。
首先,MobiLink的事件分為兩大類, 第一大類是連接事件,這類事件在全局范圍內指揮MobiLink的行為。第二類事件是表事件,這類事件在某表的范圍內指揮MobiLink的行為。MobiLink在不同的階段觸發這些事件,書寫在這些事件裡面的腳本就能指揮MobiLink的行為。
連接事件:
begin_connection:連接統一數據庫後調用 begin_synchronization:在遠程連接後, 執行任何數據改變前調用 (參數:ml_username) begin_upload:在將遠程數據庫的更改執行到 統一數據庫之前調用。 它是upload事務的一部分(參數:ml_username) end_upload:在將遠程數據庫的更改執行完成後 調用。upload(上載)階段隨之提交(參數:ml_username) begin_download:在將數據從統一數據庫抽取出 來送至遠程數據庫前調用。它是下載事務的一部分 (參數:last_download, ml_username) end_download:在遠程數據庫實施改變後調用。 下載事務隨之提交(參數:last_download, ml_username) end_synchronization:在執行完改變後與遠程 斷開連接前調用(參數:ml_username) end_connection:在與統一數據庫斷開連接前調用
兩個特殊的連接事件:
handle_error:錯誤處理 report_error:報告錯誤
表事件:
begin_upload:在遠程每張表執行 上載到統一數據庫之前調用。 (參數:ml_username, table) upload_insert:對每一行將送至統 一數據庫的插入調用。(參數:col1, col2, col3...) upload_update:對每一行將送至統一 數據庫的更新調用。(參數:SET col1, col2, ..., colN WHERE pk1, pk2, ..., pkN) upload_delete:對每一行將送至統 一數據庫的刪除調用。(參數:pk1, pk2, ..., pkN) end_upload:在將遠程表的更改執行至 統一數據庫後調用。(參數:ml_username, table) begin_download:在統一數據庫將每張 表的數據下載前調用。(參數:last_download, ml_username, table) download_cursor:每張表調用一次,將統一數據庫 的表數據下載至遠程數據庫。 (參數:last_download, ml_username) end_download:在統一數據庫將每張表的數據下載後 調用。(參數:last_download, ml_username, table)
需要注意的是,在連接事件和表事件中有一些重復的事件,例如begin_upload,不過它們作用的級別不一樣,觸發的時間也不一樣。對於所有的連接事件,我們都用調用ml_add_connection_script存儲過程來實現其中的腳本;對於所有的表事件,我們都通過調用ml_add_table_script存儲過程來實現其中的腳本。
例如:
call ml_add_connection_script('Lab', 'begin_download', 'CALL InitiateDownload()'),
第一個參數是代表腳本版本,第二個參數指明連接事件的名稱,第三個參數指定連接事件觸發時的邏輯,在這裡是調用一個存儲過程。再看一個表事件的例子:
call ml_add_table_script('demo2', 'emp', 'download_cursor', 'SELECT * FROM emp WHERE deptno=''0001'''),
第一個參數代表腳本版本,第二個參數指明該事件跟哪個事件相關,第三個參數指明事件的名稱,第四個參數是事件觸發時執行的語句。在這裡,我們指定服務器只將emp中滿足deptno='0001'的數據下載至遠程。
upload_delete、upload_update和upload_insert裡面的參數都是通過?占位符表示的。詳細信息,請參看《MobiLink 同步技術用戶指南》。
在本部分的屏幕錄像中,我們僅使用了針對emp表的update_delete和download_cursor兩個事件來指揮只有部門號為0001的數據能下載到遠程數據庫中,並且在遠程數據庫中做的刪除動作能反映到中心數據庫。在服務器啟動的過程中去掉了-za+選項,讓服務器不要自動生成腳本,去掉了-zu+的選項,通過dbmluser來添加用戶,形成真實的用戶驗證。並且在同步dbmlsync觸發同步的過程中,我們去掉了SendColumnNames=ON的擴展選項,因為我們在服務器端已經定義了同步腳本。
以下是屏幕錄像中的全部腳本:
將在上一議題的Demo中備份的數據庫文件拷貝過到新的文件夾下,在命令行中分別啟動中心與遠程數據庫:
dbeng9 center.db dbeng9 remote.db dbisql
對於remote:
CREATE PUBLICATION Lab_02 ( TABLE emp ) CREATE SYNCHRONIZATION USER "Sales02" CREATE SYNCHRONIZATION SUBSCRIPTION TO Lab_02 FOR "Sales02" TYPE 'TCPIP' ADDRESS 'host=localhost;port=2439' OPTION ScriptVersion='demo2'
對center:
CALL ml_add_table_script ('demo2', 'emp', 'upload_delete', 'DELETE emp WHERE empno=?'); CALL ml_add_table_script('demo2', 'emp', ' download_cursor', 'SELECT * FROM emp WHERE deptno=''0001''');
在控制台下:
dbmluser -c "dsn=center" -u Sales02 -p abcdefg dbmlsrv9 -dl -v+ -x tcpip -c "dsn=center" -o mlserver.mls dbmlsync -c "dsn=remote" -o dbmlsync.out -v -u Sales02 -mp abcdefg -e "sv=demo2"
其中,sv是ScriptVersion的簡寫。