유휴 연결 복원력
연결 복원력은 특정 제약 조건 내에서 중단된 유휴 연결을 다시 설정할 수 있는 원칙입니다. 데이터베이스에 연결하지 못하면 연결 복원력을 통해 클라이언트에서 자동으로 다시 연결을 시도할 수 있습니다. 연결 복원력은 데이터 원본의 속성입니다. SQL Server 2014 이상 및 Azure SQL 데이터베이스만 연결 복원력을 지원합니다.
연결 복원력은 연결 문자열에 추가할 수 있는 두 개의 연결 키워드(ConnectRetryCount
및 ConnectRetryInterval
)를 사용하여 구현됩니다.
키워드 | 값 | 기본 | 설명 |
---|---|---|---|
ConnectRetryCount |
0과 255(포함) 사이의 정수 | 1 | 포기하기 전에 끊어진 연결을 다시 설정하는 최대 시도 횟수입니다. 기본적으로 끊어진 연결을 다시 설정하기 위해 한 번 시도합니다. 0 값은 다시 연결을 시도하지 않음을 의미합니다. |
ConnectRetryInterval |
1과 60(포함) 사이의 정수 | 10 | 연결 다시 설정 시도 사이의 시간(초)입니다. 애플리케이션은 끊어진 연결을 검색하는 즉시 다시 연결을 시도하고 다시 시도하기 전에 ConnectRetryInterval 초 동안 대기합니다. ConnectRetryCount 가 0이면 이 키워드는 무시됩니다. |
ConnectRetryCount
에 ConnectRetryInterval
을 곱한 값이 LoginTimeout
보다 크면 클라이언트는 LoginTimeout
에 도달하면 연결 시도를 중지하고, 그렇지 않으면 ConnectRetryCount
에 도달할 때까지 계속 재접속을 시도합니다.
설명
연결온 복원력은 연결이 유휴 상태일 때 적용됩니다. 예를 들어 트랜잭션을 실행하는 동안 발생하는 실패는 재연결 시도를 트리거하지 않으며, 예상대로 실패하게 됩니다. 복구할 수 없는 세션 상태라고 하는 다음 상황에서는 재연결 시도가 트리거되지 않습니다.
- 임시 테이블
- 글로벌 및 로컬 커서
- 트랜잭션 컨텍스트 및 세션 수준 트랜잭션 잠금
- 애플리케이션 잠금
- EXECUTE AS/REVERT 보안 컨텍스트
- OLE 자동화 핸들
- 준비된 XML 핸들
- 추적 플래그
예시
다음 코드는 데이터베이스에 연결하고 쿼리를 실행합니다. 세션이 종료되면 연결이 중단되고 끊어진 연결을 사용하여 새 쿼리가 시도됩니다. 이 예시에서는 AdventureWorks 예시 데이터베이스를 사용합니다.
이 예시에서는 연결을 끊기 전에 버퍼링된 커서를 지정합니다. 버퍼링된 커서를 지정하지 않으면 활성 서버 쪽 커서가 있기 때문에 연결이 다시 설정되지 않습니다. 따라서 연결이 끊어지면 유휴 상태가 되지 않습니다. 그러나 이 경우 연결을 끊기 전에 sqlsrv_free_stmt()
를 호출하여 커서를 비우면 연결이 성공적으로 다시 설정됩니다.
<?php
// This function breaks the connection by determining its session ID and killing it.
// A separate connection is used to break the main connection because a session
// cannot kill itself. The sleep() function ensures enough time has passed for KILL
// to finish ending the session.
function BreakConnection( $conn, $conn_break )
{
$stmt1 = sqlsrv_query( $conn, "SELECT @@SPID" );
if ( sqlsrv_fetch( $stmt1 ) )
{
$spid=sqlsrv_get_field( $stmt1, 0 );
}
$stmt2 = sqlsrv_prepare( $conn_break, "KILL ".$spid );
sqlsrv_execute( $stmt2 );
sleep(1);
}
// Connect to the local server using Windows authentication and specify
// AdventureWorks as the database in use. Specify values for
// ConnectRetryCount and ConnectRetryInterval as well.
$databaseName = 'AdventureWorks2022';
$serverName = '(local)';
$connectionInfo = array( "Database"=>$databaseName, "ConnectRetryCount"=>10, "ConnectRetryInterval"=>10 );
$conn = sqlsrv_connect( $serverName, $connectionInfo );
if( $conn === false)
{
echo "Could not connect.\n";
die( print_r( sqlsrv_errors(), true));
}
// A separate connection that will be used to break the main connection $conn
$conn_break = sqlsrv_connect( $serverName, array( "Database"=>$databaseName) );
// Create a statement to retrieve the contents of a table
$stmt1 = sqlsrv_query( $conn, "SELECT * FROM HumanResources.Employee",
array(), array( "Scrollable"=>"buffered" ) );
if( $stmt1 === false )
{
echo "Error in statement 1.\n";
die( print_r( sqlsrv_errors(), true ));
}
else
{
echo "Statement 1 successful.\n";
$rowcount = sqlsrv_num_rows( $stmt1 );
echo $rowcount." rows in result set.\n";
}
// Now break the connection $conn
BreakConnection( $conn, $conn_break );
// Create another statement. The connection will be reestablished.
$stmt2 = sqlsrv_query( $conn, "SELECT * FROM HumanResources.Department",
array(), array( "Scrollable"=>"buffered" ) );
if( $stmt2 === false )
{
echo "Error in statement 2.\n";
die( print_r( sqlsrv_errors(), true ));
}
else
{
echo "Statement 2 successful.\n";
$rowcount = sqlsrv_num_rows( $stmt2 );
echo $rowcount." rows in result set.\n";
}
sqlsrv_close( $conn );
sqlsrv_close( $conn_break );
?>
예상 출력:
Statement 1 successful.
290 rows in result set.
Statement 2 successful.
16 rows in result set.