2012-01-17 4 views
0

연결을 설정하고 DB 트랜잭션을 수행하기 위해 아래에 언급 된 코드가 별도의 클래스 파일에 있습니다. 언젠가 연결 풀을 초과하는 다중 연결이 열리는 문제가 있습니다. 내가 코드를 밟았을 때 을 호출하지 않고 루프에서 ConnectDB()을 호출하는 코드가 있음을 발견했습니다. 그러나 나는 조건이 OraConn.State = ConnectionState.Closed이 상황을 처리해야한다고 예상했다. 여하튼 그 조건은 항상 만족되므로 다른 연결을 여는 것입니다. 내가 어디에서 잘못 되었습니까? 그리고 여기에서 채택 할 수있는 모범 사례는 무엇입니까?Oracle 다중 연결을위한 .NET Framework 데이터 공급자

Public Class Connection 
Dim Str_conn As String = "Data Source=...; User=...; password=...; Min Pool Size=10; Max Pool Size=500;" 
Public OraConn As OracleConnection 
Dim cmd As OracleCommand 
Dim dr As OracleDataReader 
Dim data_adapt As OracleDataAdapter 
Dim dt As DataTable 
Dim ds As DataSet 

Public Sub ConnectDB() 
    OraConn = New OracleConnection(Str_conn) 
    If OraConn.State = ConnectionState.Closed Then 
     OraConn.Open() 
    End If 
End Sub 

Public Sub DisconnectDB() 
    If OraConn.State = ConnectionState.Open Then 
     OraConn.Close() 
    End If 
End Sub 

Public Function get_dataset(ByVal query As String, ByRef ds As DataSet) As DataSet 
    data_adapt = New OracleDataAdapter(query, OraConn) 
    data_adapt.Fill(ds) 
    Return ds 
End Function 

Public Function get_datareader(ByVal query As String) As OracleDataReader 
    cmd = New OracleCommand(query, OraConn) 
    dr = cmd.ExecuteReader() 
    Return dr 
End Function 

Public Sub UpdateDB(ByVal query As String) 
    cmd = New OracleCommand(query, OraConn) 
    cmd.ExecuteNonQuery() 
    cmd.Dispose() 
End Sub 

클래스는 다른 클래스에서 또는 이와 같이 aspx.vb 페이지에서 직접 참조됩니다.

Public Function InsertData(ByVal var1 As String, ByVal var2 As String) As Integer 
    conn.ConnectDB() 
    Dim qryInsert As String 

    qryInsert = " INSERT INTO TABLE VALUES ('" & var1 & "', " 
    qryInsert = qryInsert & var2 & "')"   

    Try 
     conn.UpdateDB(qryInsert) 
    Catch ex As OracleException 
     If ex.Code = 1 Then 
      updData(var1, var2) 
     ElseIf ex.Code = 2091 Then 
      msgprompt("Duplicate Unique Key!", "Warning") 
     End If 
    Finally 
     conn.DisconnectDB() 
    End Try 
    Return count 
End Function 

연결은 기능 updData()에서 다시 열립니다. 나는 그것이 올바르게 닫혀 야하지만 모든 개발자에게 탭을 유지하는 것은 불가능하다는 것을 이해한다. 따라서 동일한 연결을 사용하여 연결 클래스에서 직접 제어하려고하지만 조건 If OraConn.State = ConnectionState.Closed이 도움이되지 않습니다.

I가 InsertData (...)와 같은 기능에서 ConnectDB 및 DisconnectDB에 전화를 사용하여 A 블록을 업데이트하게 아래의 코드를 넣고 제거한

UPDATE. 문제가 해결 된 것 같습니다. 하지만 예외가 발생하면 연결이 열려 있는지 알고 싶습니다. 또한 OraConn은 Using 블록에서 정의 된 공용 변수이므로 GC에 의해 처리됩니까?

Public Sub UpdateDB(ByVal query As String) 
    Using OraConn = New OracleConnection(Str_conn) 
     cmd = New OracleCommand(query, OraConn) 
     Try 
      OraConn.Open() 
      cmd.ExecuteNonQuery() 
     Catch ex As Exception 
      Throw 
     Finally 
      cmd.Dispose() 
     End Try 
    End Using 
End Sub 
+0

어디에서 ConnectDB를 방문하십니까? – Harsh

+0

데이터 소스, 사용자 이름 및 암호 세트로 간단한 연결을 만드는 것은 작동하지 않습니다. 연결 사용 풀링을 다시 사용할 수 있기를 원하면. 구체적으로'Enlist'와'Pooling'을 활성화하십시오. 자세한 내용은 [OracleConnection.ConnectionString] (http://msdn.microsoft.com/en-us/library/system.data.oracleclient.oracleconnection.connectionstring.aspx)을 확인하십시오. –

+0

@ GeekOnDemand ConnectDB – Nilanjan

답변

1

모든 연결이 완료 되 자마자 모든 연결을 닫아야합니다.

제안 :

연결을 닫기위한 가장 좋은 방법은 finally 블록에 그것을 할 것입니다. 그래도 오류가 있어도이를 잡으려면 (필요한 경우) 로그에 넣고 catch 블록에 넣은 다음 finally 블록으로 연결을 닫습니다.

UPDATE

당신은 당신의 Connection 클래스에서 한 개인 정적 카운터를 넣을 수 있습니다. 언제든지 ConnectDB()이 호출되면이 카운터를 증가시키고 각각 DisconnectDB()에서 감소시킵니다. 이제 ConnectDB()에서 카운터의 값을 확인합니다. 이렇게하면 오류가 발생하는 최소 임계 값을 초과합니다. 당신은 당신의 코드에서 유휴 연결을 발견하고 그것을 리펙토링 할 수 있습니다. 생산시이 임계 값을 높게 유지하거나 코드에서 무시하십시오.

+0

입력 해 주셔서 감사합니다. 향후 연결 문제가 발생하지 않도록 카운터를 구현할 것입니다. – Nilanjan