예외가 발생하면 SQL 연결이 닫히도록하는 올바른 방법은 무엇입니까?

StackOverflow https://stackoverflow.com/questions/141204

  •  02-07-2019
  •  | 
  •  

문제

나는 이런 식으로 보이는 패턴을 사용합니다. 이것이 괜찮은지 또는 여기에 신청하지 않는 모범 사례가 있는지 궁금합니다.

구체적으로 나는 궁금합니다. 예외가 발생하는 경우 연결이 적절하게 닫히도록 충분히 블록에있는 코드가 있습니까?

public class SomeDataClass : IDisposable
{
    private SqlConnection _conn;

    //constructors and methods

    private DoSomethingWithTheSqlConnection()
    {
        //some code excluded for brevity

        try
        {
            using (SqlCommand cmd = new SqlCommand(SqlQuery.CountSomething, _SqlConnection))
            {
                _SqlConnection.Open();
                countOfSomething = Convert.ToInt32(cmd.ExecuteScalar());
            }
        }
        finally
        {
            //is this the best way?
            if (_SqlConnection.State == ConnectionState.Closed)
                _SqlConnection.Close();
        }

        //some code excluded for brevity
    }

    public Dispose()
    {
        _conn.Dispose();
    }
}
도움이 되었습니까?

해결책

"사용"내에 데이터베이스 처리 코드를 랩핑하십시오.

using (SqlConnection conn = new SqlConnection (...))
{
    // Whatever happens in here, the connection is 
    // disposed of (closed) at the end.
}

다른 팁

.NET Framework는 이유가있는 연결 풀을 맨텐티합니다. 믿어 라! :) 데이터베이스에 연결하고 연결을 해제하기 위해 많은 코드를 작성할 필요가 없습니다.

'사용'명령문을 사용하고 'idbconnection.release ()'가 연결을 닫을 수 있음을 확신 할 수 있습니다.

정교한 '솔루션'은 버기 코드를 초래하는 경향이 있습니다. 단순한 것이 더 좋습니다.

MSDN 문서 이것을 명확하게 만드십시오 ...

  • 가까운 방법은 보류중인 거래를 롤백합니다. 그런 다음 연결 풀에 연결을 공개하거나 연결 풀링이 비활성화 된 경우 연결을 닫습니다.

당신은 아마도 연결 풀링을 비활성화하지 않았을 것입니다. 그래서 풀은 궁극적으로 "Close"라고 부른 후 연결 상태를 관리합니다. 모든 열린 연결에서 데이터베이스 서버 측에서 혼란스러워 할 수 있으므로 이것은 중요 할 수 있습니다.


  • 응용 프로그램은 두 번 이상 가까이 호출 할 수 있습니다. 예외는 생성되지 않습니다.

그렇다면 왜 폐쇄 테스트를 귀찮게합니까? 그냥 close ()에게 전화하십시오.


  • 가까이 및 폐기는 기능적으로 동일합니다.

이것이 바로 a입니다 사용 블록은 닫힌 연결을 초래합니다. 사용 당신을 위해 전화를 끊습니다.


  • 클래스의 마무리 방법에서 연결, 데이터 리더 또는 기타 관리되는 객체에서 Close 또는 폐기하지 마십시오.

중요한 안전 팁. 감사합니다, 에곤.

"_sqlConnection.state == ConnectionState.Closed"로 추측합니다!

이것은 확실히 작동 할 것입니다. 사용 명령문 안에 연결 객체 자체를 포함하는 것이 더 관례라고 생각하지만, 어떤 이유로 동일한 연결 객체를 재사용하려면 귀하가 가진 것이 좋습니다.

그러나 분명히 변경해야 할 것은 Dispose () 메소드입니다. 해당 시점에서 이미 완료되었을 수 있으므로 폐기하는 연결 객체를 참조해서는 안됩니다. 대신 권장되는 처분 패턴을 따라야합니다.

어쨌든 idisposables를 사용하고 있기 때문에. '사용'키워드를 사용할 수 있는데, 이는 기본적으로 마침내 블록에서 dispose를 호출하는 것과 동일하지만 더 좋아 보인다.

답은이 질문을 참조하십시오.

닫고 폐기 - 전화해야 할 일은 무엇입니까?

연결 수명이 단일 메소드 호출 인 경우 using 연결을 올바르게 정리할 수있는 언어의 기능. a try/finally 블록은 기능적으로 동일하며 더 많은 코드가 필요하며 IMO는 읽기 쉽지 않습니다. 연결 상태를 확인할 필요가 없습니다. Dispose 그럼에도 불구하고 연결 청소를 처리합니다.

연결 수명이 포함 된 클래스의 수명에 해당하는 경우 IDisposable 연결을 정리하십시오 Dispose.

연결을 닫는 코드를 "마지막으로"블록에 넣습니다. 마지막으로 예외가 발생하기 전에 블록이 실행됩니다. "사용"블록을 사용하는 것도 효과가 있지만, 명백한 "마침내"메소드가 더 명확합니다.

진술을 사용하는 것은 많은 개발자에게 오래된 모자이지만, 젊은 개발자는 그 사실을 알지 못할 수도 있습니다.

시도 할 필요가 없습니다. 이다 시험해보세요

이것을 제안 할 수 있습니다 :


    class SqlOpener : IDisposable
    {
        SqlConnection _connection;

        public SqlOpener(SqlConnection connection)
        {
            _connection = connection;
            _connection.Open();

        }

        void IDisposable.Dispose()
        {
            _connection.Close();
        }
    }

    public class SomeDataClass : IDisposable
    {
        private SqlConnection _conn;

        //constructors and methods

        private void DoSomethingWithTheSqlConnection()
        {
            //some code excluded for brevity
            using (SqlCommand cmd = new SqlCommand("some sql query", _conn))
            using(new SqlOpener(_conn))
            {
                int countOfSomething = Convert.ToInt32(cmd.ExecuteScalar());
            }
            //some code excluded for brevity
        }

        public void Dispose()
        {
            _conn.Dispose();
        }
    }

도움이되기를 바랍니다 :)

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top