
簡介ODAC122010Xcopy-x64.zip 是面向 .NET 開發(fā)者的 64 位 Oracle 數(shù)據(jù)訪問組件合集適合在 ASP.NET、服務(wù)端程序及 OLE DB 場景中連接 Oracle 12.2 數(shù)據(jù)庫覆蓋 ODP.NET、ASP.NET Providers 與事務(wù)服務(wù)等集成需求。壓縮包共 179 個文件、約 73.48MB包含 67 個 dll 運行時組件以及 sql、plb、ora 腳本config、exe、bat 安裝配置文件和 htm、txt 說明文檔。已有 1545 人學習下載對仍維護 .NET Framework 4/2.0 項目的讀者較有參考價值。借助其中的 Instant Client 與各 Provider可快速核對 64 位部署文件排查程序集加載、連接配置和分布式事務(wù)協(xié)調(diào)問題降低版本收集與匹配成本。1. 內(nèi)網(wǎng)服務(wù)器不許裝數(shù)據(jù)庫客戶端這套 xcopy 包就是那條備用路徑給一臺不允許運行安裝向?qū)У姆?wù)器補上數(shù)據(jù)訪問能力是 ASP.NET 老項目經(jīng)常撞上的場景站點跑在 .NET Framework 4 上要連 Oracle代碼里既有Oracle.DataAccess.Client也有幾段十年沒動過的OraOLEDB.Oracle.1還有一處事務(wù)要用到 Oramts。正常做法是裝一個客戶端但機器策略不允許安裝程序一跑就被攔。ODAC122010Xcopy-x64.zip走的是另一條路解壓、復制、跑一個批處理把 odp.net4、oledb、oramts、asp.net 這幾組 DLL 鋪到指定目錄再按需寫注冊表和 machine.config。它解決的不是“性能更好”而是“這臺機器上根本沒有安裝程序可用”。適合手上維護著 .NET Framework 老站、又不能動系統(tǒng)安裝包的從業(yè)者如果你的項目是 .NET Core / .NET 6直接引 NuGet 上的托管驅(qū)動就行這套東西反而多余。2. 拆包先認人五個子目錄與 odp.net4、oledb、oramts 的對應(yīng)關(guān)系壓縮包解開之后不要急著跑批處理先花五分鐘把目錄和 DLL 對上一遍。這個包里同時躺著好幾代驅(qū)動名字相近、版本號相近認錯了就是后面幾小時的排查。先把對應(yīng)關(guān)系列清楚再決定裝哪幾組。2.1 目錄結(jié)構(gòu)與各組件的歸屬解壓后的頂層一般能看到odp.net、asp.net、oledb、oramts幾個目錄外加install.bat、configure.bat和一份 readme。下面這張表是我自己核對時用的映射實際文件名以包內(nèi)為準但歸屬關(guān)系不會變目錄關(guān)鍵文件對應(yīng)技術(shù)棧部署時要動什么odp.net\bin\4Oracle.DataAccess.dll、oci.dll、oraociicus*.dllODP.NET 非托管驅(qū)動程序集版本 4.122.1.0進 GAC 寫HKLM\SOFTWARE\Oracle\ODP.NET\4.122.1.0odp.net\bin\2.x同名的 2.x 版本老 .NET Framework 2.0/3.5 項目同上注冊表鍵為 2.122.1.0odp.net\managedOracle.ManagedDataAccess.dll純托管驅(qū)動不依賴 oci.dll復制即可通常隨站點 bin 目錄走asp.net\binOracle.Web.dllASP.NET 成員資格、角色、會話狀態(tài)提供程序復制 改 machine.configoledb\binOraOLEDB*.dllOLE DB 提供程序OraOLEDB.Oracle.1COM 注冊 寫 Provider 注冊表項oramts\binoraMTS.dll、Oracle.Services.For.MTS相關(guān)文件分布式事務(wù)資源管理器COM 注冊 配合 MSDTC表格里最容易被忽略的是oci.dll這一列。odp.net4 和 oledb 兩組都各自帶了一份 oci 相關(guān)的動態(tài)庫它們不是擺設(shè)——非托管驅(qū)動最終要靠它跟數(shù)據(jù)庫通信。所以部署時這兩組目錄不能只挑 DLL 拷得整目錄帶過去。2.2 odp.net4 和 2.x 的分界別按“新”來選按框架版本來選很多人一看有 4就覺得統(tǒng)統(tǒng)上 4。實際判斷標準只有一個引用方的程序集版本。.NET Framework 4.0 及以上編譯出來的項目引用的是Oracle.DataAccess, Version4.122.1.02.0/3.5 時代編譯的老程序集引用的是2.122.1.0。這兩個版本號是硬綁定CLR 加載時對不上就是FileLoadException或者一個更含糊的“無法加載文件或程序集”。所以一個站點里如果同時有 Framework 4 的主站和一個老的 2.0 工具庫兩組都得鋪不能只裝一組。托管驅(qū)動Oracle.ManagedDataAccess是另一套邏輯它不注冊 GAC、不寫 ODP.NET 注冊表鍵直接放進站點的bin目錄就能用程序集版本是 4.122.1.0 那一條線。缺點是它和Oracle.DataAccess的類型不能混用命名空間雖然像但是兩個不同的程序集OracleConnection不是同一個類型。老代碼里寫死的Oracle.DataAccess.Client改造成本是有的這也就是為什么很多人最后還是回到非托管這條路。2.3 oledb 為什么還在不是所有老代碼都改得動OraOLEDB.Oracle.1在這個包里占的比重不小原因很現(xiàn)實一堆十幾年前的 ASP 頁面、VBScript 腳本、Excel 宏、SSIS 包連接串里寫的就是ProviderOraOLEDB.Oracle.1。這些代碼沒人敢動也找不到原始負責人重寫成 ODP.NET 的成本遠高于把驅(qū)動補上。OLE DB 提供程序是 COM 組件跟 .NET 程序集的部署方式完全不同。它要靠regsvr32注冊到注冊表的 CLSID 下還要在HKLM\SOFTWARE\Classes\OraOLEDB.Oracle里寫 Provider 的友好名和 CLSID 映射。install.bat 會替你干這件事手工部署時這一步最容易漏漏了之后的報錯是“未在本地計算機上注冊 OraOLEDB.Oracle.1 提供程序”看著像驅(qū)動沒裝其實是 COM 沒登記。2.4 oramts只在真的需要分布式事務(wù)時才裝oramts 對應(yīng)的是 Oracle Services for MTS作用是讓 Oracle 連接能作為資源管理器參與 MSDTC 協(xié)調(diào)的分布式事務(wù)。典型場景是一個方法里同時操作 Oracle 和 SQL Server并且要求兩邊一起提交或回滾。這一組文件不裝普通事務(wù)照跑不誤只有TransactionScope里跨庫操作才會出問題。所以部署策略上我一般把它單獨拎出來先確認業(yè)務(wù)里真有跨庫事務(wù)再裝。裝了之后還要確認 MSDTC 的配置否則一樣報錯——這個在后面第 5 章會展開。3. 免安裝部署實操install.bat 與手工搬遷兩條路認完目錄就可以動手了。有兩條路一是讓包里的install.bat一把梭二是自己控制每一步拷貝和注冊。前者快適合有管理員權(quán)限、目標目錄可以隨便定的機器后者慢但每一處改動都清楚出問題時知道從哪退回去。3.1 用 install.bat 一次鋪開以管理員身份打開命令提示符進解壓目錄執(zhí)行下面這條:: 切到解壓后的根目錄按實際路徑改 cd /d D:\pkg\ODAC122010Xcopy-x64 :: 第一個參數(shù)是組件all 表示全部第二個參數(shù)是目標目錄 install.bat all C:\oracle\odac12c :: 如果上一步只做了文件復制再單獨執(zhí)行配置 configure.bat allinstall.bat的第一個參數(shù)接受組件名常見取值是all、odp.net4、odp.net2、asp.net、oledb、oramts第二個參數(shù)是目標根目錄路徑里別帶空格和中文能省掉一堆麻煩。它的動作是把對應(yīng)目錄的文件復制過去進 GAC 的注冊程序集寫 ODP.NET 的DllPath鍵注冊 OLE DB 的 COM 組件并在 machine.config 里插入 ASP.NET 提供程序的配置節(jié)。configure.bat是“只做配置、不拷文件”的那一半?yún)?shù)同樣支持all和組件名后面可以再跟一個 machine.config 的路徑來指定要改哪個文件。我習慣把它單獨跑一次原因很簡單批處理里任何一步失敗整體退出碼不一定是非零分開跑能看出是哪一段沒成功。目標目錄建議統(tǒng)一成C:\oracle\odac12c這種結(jié)構(gòu)不要塞進Program Files。一是路徑里的空格在部分老腳本里會出問題二是后面要寫進注冊表和 PATH 的路徑越短越好排查時肉眼比對也方便。提示install.bat 修改 machine.config 之前會備份原文件擴展名通常帶.bak或時間戳。部署完成后先確認備份存在再繼續(xù)后面的步驟。3.2 不讓動系統(tǒng)目錄時的手工部署有些機器連C:\oracle都不讓寫只能放到應(yīng)用自己的目錄下比如D:\app\odac。這時候 install.bat 的全自動流程會失敗一半得手工來。核心是四件事拷文件、注冊程序集、寫注冊表、加環(huán)境變量。先拷文件按組件分組拷別整包亂鋪:: 非托管 ODP.NET 4連同目錄里的 oci 相關(guān) DLL 一起 xcopy /E /I /Y D:\pkg\ODAC122010Xcopy-x64\odp.net\bin\4 D:\app\odac\odp\4 :: OLE DB 提供程序 xcopy /E /I /Y D:\pkg\ODAC122010Xcopy-x64\oledb\bin D:\app\odac\oledb :: ASP.NET 提供程序 xcopy /E /I /Y D:\pkg\ODAC122010Xcopy-x64\asp.net\bin D:\app\odac\aspnet/E連空目錄一起拷/I讓目標被當成目錄而不是文件/Y覆蓋時不問。這三件事在一臺要反復重裝的測試機上能省很多次回車。然后是注冊表和程序集。程序集進 GAC 需要gacutil一般隨 SDK 或 VS 的命令行環(huán)境提供:: 把非托管驅(qū)動注冊進 GAC gacutil /i D:\app\odac\odp\4\Oracle.DataAccess.dll :: 寫 ODP.NET 的 DllPath讓運行庫能找到同目錄的 oci reg add HKLM\SOFTWARE\Oracle\ODP.NET\4.122.1.0 /v DllPath /t REG_SZ /d D:\app\odac\odp\4 /freg add里的鍵名4.122.1.0必須和程序集版本嚴格對應(yīng)寫錯一個數(shù)字驅(qū)動就找不到自己的依賴報錯是運行時的DllNotFoundException而不是安裝期的提示。/f表示已存在就覆蓋重裝時要用。64 位系統(tǒng)上還有個坑32 位進程讀的是HKLM\SOFTWARE\WOW6432Node\Oracle\...這條路徑。用 64 位包部署、卻讓 32 位應(yīng)用程序池去跑注冊表就寫到了另一棵樹上兩邊對不上。判斷方法見 3.3。最后是 TNS 相關(guān)。TNS_ADMIN指向放著tnsnames.ora、sqlnet.ora的目錄:: /M 表示寫系統(tǒng)級環(huán)境變量需要管理員權(quán)限 setx /M TNS_ADMIN D:\app\odac\network\adminsetx /M只影響之后新起的進程已經(jīng)開著的 IIS 應(yīng)用池不會感知到改完必須回收應(yīng)用池或者iisreset。這一點在排查“命令行能連、站點連不上”時特別關(guān)鍵。3.3 驗證部署四個檢查點按順序過裝完別急著讓業(yè)務(wù)去試自己先把四個點過一遍出問題能立刻定位到層。第一個點GAC 里有沒有這個程序集:: 列出 GAC 中所有 Oracle.DataAccess看版本號 gacutil /l Oracle.DataAccess輸出里要能看到4.122.1.0那一條并且路徑指向你剛指定的目錄。如果只有舊版本說明前面gacutil /i沒成功或者被同名舊程序集擋住了。第二個點運行庫能不能按版本號加載到它# 按完整程序集名加載成功會打印程序集全名和位置 [System.Reflection.Assembly]::Load(Oracle.DataAccess, Version4.122.1.0, Cultureneutral, PublicKeyToken89b483f429c47342) | Select-Object FullName, Location這條命令在 PowerShell 里跑注意位數(shù)要跟你的目標進程一致64 位進程用 64 位 PowerShell32 位進程用SysWOW64下的那個。加載成功但Location指向一個你沒預期的目錄那就是 GAC 里存在同版本的另一份屬于后面第 5 章要處理的情況。第三個點注冊表鍵的DllPath對不對reg query HKLM\SOFTWARE\Oracle\ODP.NET\4.122.1.0 /v DllPath值應(yīng)該等于 3.2 里寫進去的目錄。如果這里指向了舊的客戶端安裝目錄運行時會去那兒找 oci然后加載到不匹配的版本。第四個點最小連接測試。寫一個十行的控制臺程序或者直接用 PowerShell 加載驅(qū)動連一次連接串里顯式帶上Data Source先別用 EZConnect 之外的別名排除 tnsnames 的干擾。四個點都過再讓站點去引。4. ASP.NET 站點接入machine.config、web.config 與 Oracle.Web 的配置順序驅(qū)動鋪好了接下來是讓站點用上。這一步的順序很重要先改 machine.config 注冊提供程序再改 web.config 引用最后調(diào)權(quán)限。反過來做中間任何一步出錯都會得到一個看不出根因的異常。4.1 Oracle.Web 在 machine.config 里的位置Oracle.Web.dll提供的是 Membership、Role、Profile、SessionState 這幾類 Provider它們要被 ASP.NET 的 Provider 模型識別必須在 machine.config 的system.web節(jié)里登記。configure.bat 的asp.net選項做的就是這件事它會往membership、roleManager、profile、sessionState里各插一段。如果機器上跑著多個站點、只有一個要用 Oracle 的提供程序我傾向于不動 machine.config改在站點自己的 web.config 里寫完整定義。原因很實際machine.config 是全局的改壞了所有站點一起掛而且回滾要靠備份文件手工還原。web.config 出問題最多影響一個應(yīng)用刪掉重啟就好。4.2 web.config 的連接串與 Provider 定義下面這段是一個最小可用的配置把連接串和成員資格提供程序都寫在站點級configuration connectionStrings !-- providerName 必須和實際使用的驅(qū)動對上非托管寫 Oracle.DataAccess.Client -- add nameOraAspNetConString connectionStringUser Idapp;Password***;Data SourceORCLPDB;Poolingtrue;Min Pool Size1; providerNameOracle.DataAccess.Client / /connectionStrings system.web membership defaultProviderOracleMembershipProvider userIsOnlineTimeWindow15 providers add nameOracleMembershipProvider typeOracle.Web.Security.OracleMembershipProvider, Oracle.Web, Version4.122.1.0, Cultureneutral, PublicKeyToken89b483f429c47342 connectionStringNameOraAspNetConString applicationName/ enablePasswordRetrievalfalse enablePasswordResettrue requiresQuestionAndAnswerfalse requiresUniqueEmailfalse passwordFormatHashed maxInvalidPasswordAttempts5 minRequiredPasswordLength8 / /providers /membership /system.web /configurationtype屬性里的四段式程序集名不能省程序集名、版本、區(qū)域、公鑰標記少一段就會走到“按簡單名加載”的寬松匹配上可能加載到別的版本。connectionStringName要和上面connectionStrings里的name完全一致大小寫敏感。applicationName決定數(shù)據(jù)行的歸屬多個站點共用一個庫時這一項寫錯會導致用戶互相看不見排查起來非常費勁。passwordFormat選Hashed之后enablePasswordRetrieval必須是false兩個參數(shù)是聯(lián)動的配錯會在站點啟動時直接拋配置異常。4.3 應(yīng)用程序池標識與目錄權(quán)限驅(qū)動文件和配置文件都就位了還有一個經(jīng)常被忘的環(huán)節(jié)應(yīng)用程序池用哪個身份跑那個身份就得能讀到部署目錄和注冊表鍵。默認的ApplicationPoolIdentity是一個虛擬賬戶對D:\app\odac這種自建目錄通常沒有讀權(quán)限。表現(xiàn)是站點啟動時報“拒絕訪問”或者提供程序初始化失敗異常堆棧指向配置文件加載看著像配置錯其實是權(quán)限問題。給權(quán)限的方式是給對應(yīng)的虛擬賬戶授權(quán)而不是給Everyone:: 給應(yīng)用程序池虛擬賬戶讀執(zhí)行權(quán)限池名按實際改 icacls D:\app\odac /grant IIS APPPOOL\YourAppPool:(OI)(CI)RX /T(OI)(CI)表示繼承到子文件和子目錄RX是讀加執(zhí)行。加完回收應(yīng)用池再試。這一步在測試機上經(jīng)常被跳過因為測試時用的是管理員身份跑的控制臺程序權(quán)限天然是夠的一上 IIS 就翻車。4.4 兩條通路的代碼驗證配置改完用一小段代碼把 ODP.NET 和 Oracle.Web 各驗一遍using System; using Oracle.DataAccess.Client; // 非托管驅(qū)動命名空間 using Oracle.Web.Security; // Oracle.Web 提供程序 class Probe { static void Main() { // 通路一直接用 ODP.NET 打開連接確認驅(qū)動與 oci 都正常 string cs User Idapp;Password***;Data SourceORCLPDB;Poolingtrue;; using (var conn new OracleConnection(cs)) { conn.Open(); using (var cmd new OracleCommand(select 1 from dual, conn)) { Console.WriteLine(ODP.NET OK: cmd.ExecuteScalar()); } } // 通路二通過 Oracle.Web 的提供程序創(chuàng)建用戶確認 Provider 配置生效 var provider Membership.Provider as OracleMembershipProvider; if (provider null) throw new InvalidOperationException(默認成員資格提供程序不是 Oracle 實現(xiàn)); MembershipCreateStatus status; provider.CreateUser(probe_user, Pssw0rd!, probeexample.com, null, null, true, null, out status); Console.WriteLine(Oracle.Web status: status); } }第一段驗證的是驅(qū)動層能連上、能執(zhí)行說明Oracle.DataAccess.dll、oci 依賴、TNS_ADMIN三者都對。第二段驗證的是配置層Membership.Provider拿到的類型不對說明 web.config 里的type或defaultProvider有問題拿到了但CreateUser拋異常通常是表結(jié)構(gòu)沒初始化或者連接串指向的庫不對。這里用as轉(zhuǎn)換而不是強轉(zhuǎn)是為了在類型不匹配時給出一個能看懂的異常而不是一個籠統(tǒng)的InvalidCastException。做部署驗證時錯誤信息本身就是排查的一半。5. 避坑與排查五類翻車現(xiàn)場的現(xiàn)象、成因與處置部署這套包踩過的坑八成集中在下面五類。每一條我都按“看到什么、為什么、怎么辦”寫方便對著報錯直接查。5.1 BadImageFormatException位數(shù)不匹配現(xiàn)象站點一訪問就拋BadImageFormatException提示“試圖加載格式不正確的程序”堆棧停在加載Oracle.DataAccess那一行。原因應(yīng)用程序池開啟了 32 位兼容Enable 32-Bit Applications True進程是 32 位的但裝的是 x64 的 xcopy 包GAC 里只有 64 位程序集。反過來也成立64 位進程加載了 32 位驅(qū)動。解決先確認應(yīng)用池的位數(shù)設(shè)置再決定裝哪個包。要么把應(yīng)用池改成 64 位并確認沒有其他 32 位依賴要么另外找 32 位包鋪一份。兩個都裝也行但注冊表得分開寫32 位進程讀WOW6432Node那棵樹GAC 視角也不同這一點在 3.2 里提過。5.2 加載到舊版本GAC 里躺著同名程序集現(xiàn)象代碼明明按 4.122.1.0 編譯運行時卻報方法不存在或者行為異常用Assembly.Load打印Location發(fā)現(xiàn)指向了一個舊的客戶端安裝目錄。原因機器上原本裝過數(shù)據(jù)庫客戶端或者更早的 ODACGAC 里有同名的Oracle.DataAccess。GAC 的查找規(guī)則優(yōu)先匹配版本但如果 web.config 里配了bindingRedirect或者引用的版本被合并過就會加載到舊的那份。更隱蔽的是DllPath指向舊目錄oci 版本和新驅(qū)動不匹配表現(xiàn)為連接時崩潰而不是加載時崩潰。解決gacutil /l Oracle.DataAccess列出全部副本逐個比對版本和路徑確認后卸載不用的版本或者在 web.config 里顯式寫bindingRedirect把舊版本重定向到新版本。DllPath鍵也要一起核對別只改一半。5.3 ORA-12154 / ORA-12541找不到連接描述符現(xiàn)象命令行用 sqlplus 能連站點連不上報ORA-12154: TNS: 無法解析指定的連接標識符或者報ORA-12541: TNS: 無監(jiān)聽程序。原因前者的九成是TNS_ADMIN沒生效——改了系統(tǒng)變量但應(yīng)用池沒回收進程里還是舊值或者tnsnames.ora放在了驅(qū)動自帶的network\admin下而實際生效的是另一個目錄。后者多半是連接串里的主機端口寫錯或者服務(wù)端監(jiān)聽確實沒起。解決先在應(yīng)用池的身份下確認環(huán)境變量別用你自己的登錄會話去看。臨時驗證可以在 web.config 的連接串里直接用 EZConnect 寫法host:port/service_name繞開 tnsnames能連就說明是解析問題而不是網(wǎng)絡(luò)問題。定位清楚再決定是修TNS_ADMIN還是修別名文件。5.4 OraOLEDB.Oracle.1 未注冊COM 沒登記現(xiàn)象老的 ASP 頁面或者 SSIS 包報“未在本地計算機上注冊 OraOLEDB.Oracle.1 提供程序”。原因文件拷過去了但 COM 組件沒注冊或者注冊了但位數(shù)不對32 位進程找不到 64 位的注冊項。解決用管理員權(quán)限對OraOLEDB*.dll執(zhí)行regsvr3232 位組件要用SysWOW64\regsvr32.exe。注冊完在注冊表里確認HKLM\SOFTWARE\Classes\OraOLEDB.Oracle下的 CLSID 指向正確路徑。注意 OLEDB 提供程序依賴 oci整目錄拷貝別只挑一個 DLL。5.5 Oramts 裝了還是事務(wù)失敗MSDTC 沒配現(xiàn)象TransactionScope里同時操作兩個庫提交時報分布式事務(wù)相關(guān)的錯誤或者干脆超時。原因oramts 只是讓 Oracle 連接能參與分布式事務(wù)真正的協(xié)調(diào)者是 MSDTC。MSDTC 未開啟網(wǎng)絡(luò) DTC 訪問、未允許入站/出站、防火墻擋了 RPC 端口都會讓事務(wù)在提升階段失敗。另外連接串里如果沒開enlist連接根本不會自動登記到事務(wù)里。解決先確認連接串行為再檢查 MSDTC 的安全配置網(wǎng)絡(luò) DTC 訪問、事務(wù)管理器通信、入站出站授權(quán)最后看防火墻。這一條排查鏈路長我一般從“能不能只用本地事務(wù)”倒推如果業(yè)務(wù)允許把跨庫操作拆開能省掉整條鏈路的不確定性。6. 版本共存與回滾把這次部署做成可撤銷的一步部署這套東西最容易留下的隱患不是裝不上而是裝完之后沒法干凈地退回去。GAC 里的程序集、注冊表鍵、machine.config 的改動、COM 注冊四樣東西分散在四個地方出問題時想還原得靠記憶。我現(xiàn)在做這類部署會強制留一份可撤銷的清單。先做備份四樣東西各存一份對象備份方式還原命令GAC 程序集記錄gacutil /l的輸出存成文本gacutil /u Oracle.DataAccess,Version4.122.1.0,...ODP.NET 注冊表鍵reg export導出整個Oracle\ODP.NET子樹reg import odac_backup.regmachine.config復制一份帶日期的副本直接覆蓋回原路徑OLE DB COM 注冊記錄 CLSID 和 DLL 路徑regsvr32 /u反注冊導出注冊表這一步用一行命令就夠:: 部署前導出出問題一條命令還原 reg export HKLM\SOFTWARE\Oracle\ODP.NET D:\backup\odpnet_before.reg /y reg export HKLM\SOFTWARE\Classes\OraOLEDB.Oracle D:\backup\oledb_before.reg /y/y覆蓋同名文件路徑提前建好。等真出事的時候你不會有心情去找“備份到底存哪了”。版本共存的處理上我的做法是同一臺機器只保留一條主線。要么全用非托管Oracle.DataAccess4.122.1.0要么全用托管Oracle.ManagedDataAccess不要在一個應(yīng)用里混?;煊玫闹苯雍蠊穷愋筒患嫒軴racleConnection來自兩個不同程序集編譯期不報錯、運行期轉(zhuǎn)換失敗。如果確實有老代碼改不動就讓它單獨跑在一個應(yīng)用池里用舊版本跟新站物理隔開。還有一個驗證習慣值得養(yǎng)成部署完成后在測試機上跑一次“斷開再連”的完整流程而不是只用一條select 1 from dual驗證。具體做法是把應(yīng)用池停掉、清空連接池、再啟動然后走一遍登錄和一次跨庫事務(wù)。連接池里殘留的舊連接會掩蓋掉很多問題只有重啟之后第一次建連才暴露真實的配置狀態(tài)。最后說個我自己的教訓。早些年做這類 xcopy 部署我圖省事直接在機器上跑install.bat all跑完就交付了。兩個月后那臺機器要升級運維問我“當初改了哪些地方”我翻不出任何記錄只能對著注冊表和 machine.config 一點點比對花了整整一個下午。從那以后我每次做 xcopy 部署都強制走一遍“先導出注冊表、再跑批處理、最后記一份變更清單”的流程清單里連目標目錄和DllPath的值都寫清楚。慢十分鐘省一下午。希望幫到你。本文還有配套的精品資源點擊獲取