本文討論使用 Microsoft JDBC Driver for SQL Server 連線到 Azure SQL Database 時發生的問題。 如需連線到 Azure SQL Database 的詳細資訊,請參閱:
詳細資料
若要連線到 Azure SQL Database,您應連線至 master 資料庫以呼叫 SQLServerDatabaseMetaData.getCatalogs。
Azure SQL Database 不支援從使用者資料庫傳回整組目錄。
SQLServerDatabaseMetaData.getCatalogs 會使用 sys.databases 檢視取得目錄。 要了解 Azure SQL Database 上的 SQLServerDatabaseMetaData.getCatalogs 行為,請參閱 sys.databases 中關於權限的討論。
登入逾時
當你連接到 Azure SQL 資料庫時,loginTimeout預設的 30 秒是合理的起點。 對於已啟用自動暫停的 Azure SQL Database 無伺服器,請將其調高,使其足以支應驅動程式在資料庫恢復運作期間進行的連線重試。 欲了解更多資訊,請參閱 「連接至自動暫停的無伺服器資料庫」。 要設定 loginTimeout,請參見 設定連接屬性。
連線中斷
當你連接到 Azure SQL Database 時,網路元件(例如防火牆)可能會在一段時間的閒置連線後終止。 在此語境下,閒置連接有兩種類型:
在 TCP 層處於閒置狀態時,連線可能會被任何數量的網路裝置中斷。
被 Azure SQL 閘道視為閒置,可能正在發生 TCP keepalive 訊息(這會使連線從 TCP 的角度來看不算閒置),但在 30 分鐘內沒有任何作用中的查詢。 在此狀況下,閘道會在 30 分鐘時判定 TDS 連線閒置並結束連線。
若要解決第二點並避免閘道終止閒置連線,您可以:
使用重新導向連線原則來設定您的Azure SQL 資料來源。
透過輕量活動讓連線保持作用中狀態。 不建議使用此方法,應只在沒有其他可能的選擇時使用。
若要解決第一點並避免網路元件卸除閒置連線,請在載入該驅動程式的作業系統上設定下列登錄設定或其非 Windows 的對等項目:
注意
從適用於 SQL Server 的 Microsoft JDBC 驅動程式 10.2 版開始,驅動程式會自動在資料庫連線期間建立的通訊端上設定下列保持作用中值,並覆寫下表中定義的 OS 預設值。 此自動設定僅在支援設定套接字保持連線選項的 Java 版本上執行。 在 Linux 和 macOS 上,Java 8+ 的最新更新支援此設定。 在 Windows 上,Java 17+ 的最新更新支援此設定。
| 登錄檔設定 | 建議值 |
|---|---|
| HKEY_LOCAL_MACHINE \ SYSTEM \ CurrentControlSet \ Services \ Tcpip \ 參數 \ KeepAliveTime | 30000 |
| HKEY_LOCAL_MACHINE \ SYSTEM \ CurrentControlSet \ Services \ Tcpip \ Parameters \ KeepAliveInterval | 1000 |
| HKEY_LOCAL_MACHINE \ SYSTEM \ CurrentControlSet \ Services \ Tcpip \ 參數 \ TcpMaxDataRetransmissions | 10 |
重新啟動電腦,讓這些登錄設定生效。
KeepAliveTime 與 KeepAliveInterval 值是以毫秒為單位。 這些設定會使無回應的連線在 10 到 40 秒內中斷。 如果在傳送「保持運作」封包之後沒有收到任何回應,則會每秒重試一次,最多 10 次。 如果在這段時間內沒有收到任何回應,就會中斷用戶端通訊端的連線。 視環境而定,建議您增加 KeepAliveInterval 以配合可能導致伺服器超過 10 秒無法回應的已知中斷情形 (例如虛擬機器移轉)。
注意
在 Windows Vista 或 Windows 2008 與更新版本上,無法控制 TcpMaxDataRetransmissions。
若要在 Azure VM 中加以設定,請建立啟動工作以新增登錄機碼。 例如,您可以將下列啟動工作加入至服務定義檔:
<Startup>
<Task commandLine="AddKeepAlive.cmd" executionContext="elevated" taskType="simple">
</Task>
</Startup>
然後,將 AddKeepAlive.cmd 檔案加入至您的專案。 將 [複製到輸出目錄] 設定設為 [永遠複製]。 下列指令碼是範例 AddKeepAlive.cmd 檔案:
if exist keepalive.txt goto done
time /t > keepalive.txt
REM Workaround for JDBC keep alive on Azure SQL
REG ADD HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters /v KeepAliveTime /t REG_DWORD /d 30000 >> keepalive.txt
REG ADD HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters /v KeepAliveInterval /t REG_DWORD /d 1000 >> keepalive.txt
REG ADD HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters /v TcpMaxDataRetransmissions /t REG_DWORD /d 10 >> keepalive.txt
shutdown /r /t 1
:done
將伺服器名稱附加至連接字串中的 userId
在 Microsoft JDBC Driver for SQL Server 4.0 版之前,若要連線到 Azure SQL Database,您必須將伺服器名稱附加至連接字串中的 UserId。 例如 user@servername。 從 Microsoft JDBC Driver for SQL Server 4.0 版開始,您不再需要將 @servername 附加至連接字串中的 UserId。
啟用加密需要設定 hostNameInCertificate
在 Microsoft JDBC Driver for SQL Server 7.2 版之前,連線到 Azure SQL Database 時,如果您指定了 encrypt=true (如果連接字串中的伺服器名稱為 shortName.domainName,請將 hostNameInCertificate 屬性設定為 *.domainName),則應該指定 hostNameInCertificate。 從驅動程式 7.2 版開始,這個屬性是選擇性的。
例如:
jdbc:sqlserver://abcd.int.mscds.com;databaseName=myDatabase;user=myName;password=<password>;encrypt=true;hostNameInCertificate=*.int.mscds.com;