以零停機執行自訂 X++ 指令碼
重要
Some or all of the functionality noted in this article is available as part of a preview release. The content and the functionality are subject to change. For more information about preview releases, see Service update availability.
此功能允許您上傳和執行包含自訂 X++ 指令碼的可部署套件,而無需透過 Microsoft Dynamics Lifecycle Services (LCS) 或暫止您的系統。 因此,您可以更正輕微的資料不一致,而不會造成任何中斷性停機。
使用 X++ 指令碼糾正輕微資料不一致的好處是系統在執行指令碼時會根據需要自動調整所有相關資料表。 這種方法有助於確保更正的完整性,並有助於將引入新的不一致的風險降至最低。
重要
此功能僅用於糾正輕微的資料不一致。 不得將其用於以下目的或任何其他目的:
- 資料收集
- 結構描述更改
- 資料移轉或其他長時間執行的過程
- 可以透過其他方式更正的資料的更正,例如常規業務流程、資料一致性工具或其他自助服務工具
該功能允許授權使用者直接更改實體及其記錄,而無需執行與這些實體關聯的業務邏輯。 這些更改可能會導致資料完整性問題。 因此,您的組織可能要求您在執行指令碼之前和/或之後獲得內部和外部審計員 (或其他等效利益相關者) 的核准和簽字。 出於合規性原因,影響某些特徵的變更可能還必須在外部報表 (例如財務報表) 中揭露或向政府當局報表。 您的組織對透過此功能對其資料進行的任何更改、對這些更改的任何核准和簽署或揭露以及對適用法律的遵守負全部責任。 您承擔使用此功能的所有風險。
上傳到系統中的所有可部署套件都經過強制性工作流程。 作為安全預防措施,並幫助確保職責分離,上傳可部署套件的使用者不允許核准它以用於工作流程中的後續步驟。 另一個使用者必須核准它。 但是,在套件被核准後,上傳它的使用者將被允許完成剩餘的步驟。
系統要求所有可部署的套件都經過測試執行。 在允許指令碼在生產資料上執行之前,使用者必須透過選取 接受測試記錄 來驗證輸出是否正確。 如果輸出不正確,使用者必須透過選取 放棄 將套件標記為失敗。 在這種情況下,將不允許指令碼在生產資料上執行。
每個上傳的套件都儲存在系統中,並透過定義的事件工作流程。 對於每個事件,系統都會保留一個記錄,其中套件括時間戳記和執行該事件的人的身份。 透過這種方式,系統確儲存在稽核線索。
如下圖所示,系統提供了有關每個可部署套件如何在 X++ 中執行以及觸及哪些實體的詳情。
為使用者指派職責以控制存取
本功能提供下列責任。 管理員可以使用這些職責來幫助控制對該功能的存取。
- 維護自訂指令碼 – 該職責授予在環境中上傳、測試、驗證和執行自訂 X++ 指令碼的能力 (使用者驗收測試[UAT]和生產)。
- 核准自訂指令碼 – 此職責授予核准上傳的自訂 X++ 指令碼的能力。 核准是測試、驗證和執行任何指令碼之前的強制性步驟。
為了幫助最大程度地降低惡意動作的風險,每個指令碼都必須由上傳它的使用者以外的使用者明確核准。 在您可以在您的組織中使用此功能之前,管理員必須將上述職責指派給至少兩個相關且高度信任的使用者。 儘管單個使用者可以同時承擔這兩項職責,但該使用者仍然無法核准他們自己的指令碼。
建立可部屬的套件
該功能需要一個可以在 Visual Studio 中建立的常規可部署套件。 如需相關說明,請參閱建立可部署的模型套件。
您的可部署套件必須包含一個可執行的 X++ 類。 換句話說,它必須有一個類,其中包含具有以下簽名的方法。
public static void main(Args _args)
注意
主要方法的名稱必須是小寫的。
代碼範例
以下代碼範例顯示了如何構建可部署套件。
class MyScriptClassForIssueXYZ
{
public static void main(Args _args)
{
if (curExt() != 'DAT')
{
throw error("This script must run in the DAT company!");
}
ttsbegin;
MyTable myTable;
update_recordset myTable
setting myField = 17
where myTable.myReference == 'xyz';
if (myTable.RowCount() != 1)
{
throw error("Not updating the expected row!");
}
info("Success");
ttscommit;
}
}
最佳實務作法
以下清單描述了成功編寫、實作和執行指令碼的一些最佳做法。 該清單並不詳盡,應僅視為指導。
- 務必 在指令碼末尾寫一條成功訊息。 這樣,您將能夠看到指令碼執行無異常。
- 務必 新增對交易範圍的明確處理。
- 務必 使用現有的業務邏輯,例如
update()
方法,但是 請勿 透過使用doUpdate()
、doInsert()
,和doDelete()
方法略過業務邏輯。 這種方法將有助於確保正確處理相關資料。 它還將顯著降低進一步資料不一致的風險。 - 務必 宣告公司背景。 這種方法將在指令碼執行階段暴露常見錯誤。 例如,它將揭示指令碼是否在錯誤的公司中執行。
- 務必 宣告受影響記錄的數量符合您的期望。 這種方法將揭示在準備指令碼時資料是否在系統中意外移動。
- 務必 為每個指令碼使用唯一的類名 (例如,透過在名稱中包含對工作項目的參考)。 當您上傳指令碼時,此方法將防止出現名稱衝突問題。 如果需要對指令碼進行新的迭代,請務必給它一個新名稱。
- 務必 先在非生產環境中測試每個指令碼。 測試對相關資料的預期影響和意外副作用。 確保所有可能受到影響的業務流程事後都能順利完成。
上傳並執行可部署的套件
使用以下過程上傳和執行指令碼。
在您的財務和營運應用程式中,進入 系統管理>定期工作>資料庫>自訂指令碼。
選取 上傳。
選取您如本主題前面所述建立的可部署套件。 系統將提示您指定指令碼的用途。
該指令碼現在必須由上傳它的使用者以外的使用者核准。 核准者必須遵循以下步驟:
- 進入 系統管理>定期>資料庫>自訂指令碼。
- 選取要核准的指令碼,然後選取 詳情。
- 在動作窗格上,在 生產工作流程 索引標籤上的 開始 群組中,選取 核准 或 拒絕。 如果您選取 核准,指令碼會被標記為已核准並已解鎖以進行測試。 如果您選取 拒絕,指令碼會被鎖住。 在這兩種情況下,事件都會被記錄下來,並且指令碼的副本會儲存在系統中。
必須對指令碼進行測試,以確保它完成了預期的工作。 測試者可以是上傳者或核准者,也可以是具有所需權限的第三個使用者。 測試者必須遵循以下步驟:
進入 系統管理>定期>資料庫>自訂指令碼。
選取要測試的指令碼,然後選取 詳情。
在「動作窗格」上,在 處理工作流程 索引標籤上的 測試 群組中,選取 執行測試。 該指令碼在一個臨時交易中執行,系統將在收集各種記錄和 SQL 陳述式時自動中止該交易。
指令碼完成執行後,查看記錄並驗證結果是否符合您的預期。 請執行以下其中一個步驟:
- 如果您對測試結果感到滿意,請在動作窗格的 流程工作流程 索引標籤上的 測試 組中選取 接受測試記錄 以允許執行指令碼。 事件記錄檔將反映指令碼已經過測試的事實,並指出誰測試了它以及何時測試。
- 如果您對測試結果感到不滿意,請在動作窗格的 流程工作流程 索引標籤上的 編輯 組中選取 放棄 以防止執行指令碼。 系統將保留指令碼的副本及其歷史記錄。
當您確定指令碼符合您的期望時,在動作窗格的 流程工作流程 索引標籤上的 執行 組中選取 執行 以執行它。 此命令與之前的測試執行執行相同的動作,但交易將在最後送出。
指令碼完成執行後,檢查結果,並確認指令碼按預期執行。 請執行以下其中一個步驟:
- 如果您對結果感到滿意,請在動作窗格的 流程工作流程 索引標籤上的 結束 組中選取 目的已解決。 事件記錄檔將反映指令碼成功執行的事實,並指出誰驗證了指令碼以及何時驗證。 指令碼已儲存,但現在已鎖定,無法再次執行。
- 如果您對結果感到不滿意,請在動作窗格的 流程工作流程 索引標籤上的 結束 組中選取 目的未解決。 事件記錄檔將反映指令碼未能實現其預期目的的事實,並將指出誰執行了指令碼以及何時執行。 指令碼已儲存,但現在已鎖定,無法再次執行。 但是,系統不會自動復原指令碼動作。 您可能必須編寫、匯出和執行一個新指令碼來復原失敗的指令碼對您的系統造成的影響。
您在最後一步中的選取定義了指令碼的最終狀態。 您可以根據需要重複該過程。
透過 LCS 上傳並執行可部署的套件
如前一節所述,您可以將其上傳到 LCS 並使用常規過程進行部署,而不是透過財務和營運應用程式應用程序的使用者介面部署可部署套件。 如需相關資訊,請參閱從命令行安裝可部署的套件。
雖然這種方法的限制較少,但它提供的錯誤保護較少。 此外,由於它需要重新啟動所有伺服器,因此會導致一些停機狀況。