잠긴 파일 처리
한대성
MS SQL Server MVP
에이디컨설팅 책임 컨설턴트 | SQLLeader.com 운영자
Question
간단한 예로 특정 파일을 열고 있는 상태에서 해당 파일을 지우는 작업을 수행하게 되면 다음과 같이 에러가 발생합니다.
Foreach 루프 컨테이너 등을 이용하여 여러 파일을 삭제할 때 이와 같이 다른 프로세스에서 사용중인 파일은 건너뛰도록 설정하는 방법에 대해 살펴보겠습니다.
간단히 해당 작업의 MaximumErrorCount 속성을 1에서 2로만 변경해도 에러가 발생했을 때 에러라고 출력하지 않고 그냥 성공으로 처리합니다.
하지만, 이렇게 설정한 경우에는 다른 프로세스에서 사용 중이어서 삭제가 실패한 경우 외에도 파일이 없는 경우와 같이 다른 모든 유형에 대해서도 에러를 발생하지 않고 성공으로 처리하기 때문에 문제가 있을 수 있습니다.
다른 일반적인 방법으로 선행 제약 조건에서 실패로 경로를 설정한 후, 후행 작업을 구현할 수도 있습니다.
일반적인 방법이긴 하지만 필자 개인적으로는 선호하지 않는 유형입니다.
제어 흐름 내에서 한 작업의 실패는 상위 컨테이너까지 전파됩니다. 즉, 위와 같이 파일 시스템 작업이 실패가 되어 다음 단계로 진행되어서 정상적으로 처리가 되었더라도 해당 작업의 상위 컨테이너인 패키지는 자식 구성 요소 중에 실패한 놈(^^)이 있기 때문에 실패로 처리합니다.
간단한 예로, 위의 패키지를 SQL Agent의 작업으로 등록해서 실행하면 다음과 같이 실패로 처리됩니다.
이러한 이유 때문에 가급적 패키지에서 에러를 발생시키지 않는 방법으로 구현하고자 합니다.
다음과 같은 방법은 어떨까요? 파일 시스템 작업 전에 해당 파일의 잠금 상태를 확인한 후, 해당 파일이 잠겨있을 경우에는 작업을 진행하지 않도록 수행하는 것입니다.
이를 구현하기 위해 우선 패키지에 FileLockYN 이라는 String형 변수를 하나 추가합니다.
파일 시스템 작업 전에 스크립트 작업을 추가한 후, 다음과 같이 설정합니다.
스크립트 작업의 ReadWriteVariables에 방금 추가한 FileLockYN 변수를 설정하고, 스크립트 디자인(S)를 열어 다음과 같은 스크립트를 입력합니다. 본 예제에서는 TargetFile이라는 파일 연결을 사용합니다.
Imports System Imports System.Data Imports System.Math Imports Microsoft.SqlServer.Dts.Runtime Imports System.IO Imports System.Security.Principal Imports System.Security.Permissions
Public Class ScriptMain Public Sub Main()
Dim FileName As String FileName = Dts.Connections("Target").ConnectionString If IsFileInUse(FileName) < 0 Then Dts.Variables("FileLockYN").Value = "Y" Else Dts.Variables("FileLockYN").Value = "N" End If Dts.TaskResult = Dts.Results.Success End Sub
Function IsFileInUse(ByVal filename As String) As Integer If File.Exists(filename) Then On Error GoTo noFileHandles Dim oFp As FileIOPermission = New FileIOPermission(FileIOPermissionAccess.Write, filename) oFp.Assert() Dim objWriter As New IO.StreamWriter(File.Open(filename, IO.FileMode.Open)) objWriter.Close() objWriter = Nothing
IsFileInUse = 1 GoTo endFunc Else GoTo noSuchFile End If
noSuchFile: IsFileInUse = -3 Exit Function inUse: IsFileInUse = -1 Resume endFunc
noFileHandles: IsFileInUse = -2 Resume endFunc endFunc: End Function
End Class |
그런 다음, 스크립트 작업과 파일 시스템 작업 사이의 선행 제약 조건(연결선)에 다음과 같은 조건식을 입력합니다.
만약 파일이 잠겨 있는 경우에는 다음과 같이 삭제 작업으로 진행하지 않습니다.
파일이 잠겨있지 않은 경우에는 다음과 같이 삭제 작업을 진행합니다.
본 게시판에 실린 글은 누구나 복사하셔서 이용하셔도 되지만, 반드시 출처(SQLLeader.com) 및 링크를 밝혀주셔야 합니다.
'연구개발 > DTS & SSIS' 카테고리의 다른 글
동적 대상 설정하기 (0) | 2011.08.27 |
---|---|
스크립트 변환을 이용한 RowNumber 및 파생열 만들기 (0) | 2011.08.27 |
스크립트 변환으로 RowNumber 구현하기 (0) | 2011.08.27 |
TEXT 형이 포함된 Excel 데이터 가져오기 문제 (0) | 2011.08.27 |
부모 패키지에서 자식 패키지 변수값 읽어오기 (0) | 2011.08.27 |