Если консольная программа завершается, будут ли соединения с базой данных, используемые в программе, оставаться открытыми? - PullRequest
6 голосов
/ 07 июня 2009

В Java и C # они оба имеют что-то вроде System.terminate (). Если в моей программе есть открытые соединения с базой данных, средства чтения базы данных и переменные команд базы данных, и я завершаю свою программу в предложении catch, будут ли ресурсы базы данных продолжать использоваться? или они будут освобождены автоматически после завершения всей моей программы?

Как обычно я должен обрабатывать такие случаи, чтобы всегда освобождать соединения с базой данных, будь то через обычное завершение программы или неожиданное завершение программы? Есть хорошие практики?

Ответы [ 8 ]

6 голосов
/ 07 июня 2009

После завершения процесса все связанные ресурсы (включая память, дескрипторы, соединения и т. Д.) Будут освобождены.

Обычно в C # вы используете оператор Dispose pattern / using для управления дефицитными ресурсами.

5 голосов
/ 07 июня 2009

Если вы специально не закроете соединение, они останутся открытыми до истечения времени ожидания.

Несколько раз я узнал об этом на C #. Лучшие практики требуют закрытия / закрытия ресурсов, которые, как вы знаете, вам больше не понадобятся. Файловые потоки ввода / вывода, соединения с БД и т. Д.

1 голос
/ 07 июня 2009

Если вы работаете с SQL Server, вы можете просмотреть sysprocesses или запустить sp_who2. Я проверил это на своей машине, и соединения закрываются, т. Е.

Console.Write("Opening connection");
Console.ReadLine();
SqlConnection connection = new SqlConnection(@"Data Source=.\SQLEXPRESS;Initial Catalog=SeniorMail;Integrated Security=SSPI;");
connection.Open();
SqlCommand command = new SqlCommand("SELECT count(*) from Account", connection);
Console.Write("Running sql");
Console.ReadLine();
int? count = command.ExecuteScalar() as int?;
Console.Write("Now I'll throw an exception");
Console.ReadLine();
int a = 0, b = 1, c = 0;

try
{
    c = b / a;
}
catch
{
    Environment.Exit(1);
}

Я проверил sp_who2 по обе стороны от «Теперь я брошу исключение», и я вижу, что после выхода из приложения соединение исчезло.

1 голос
/ 07 июня 2009

Когда процесс завершается, все дескрипторы файлов, которые он открывает, должны быть освобождены операционной системой. Файловые дескрипторы включают файлы и сокеты, которые обычно покрывают ваши соединения с базой данных.

Все, что вам говорит, это то, что когда ваш клиент завершает работу, его соединения закрываются. Он не говорит вам, что делает сервер. В зависимости от того, как оно написано, вполне возможно, что сервер продолжит держать свои соединения открытыми, ожидая сообщений от клиента, которые никогда не будут поступать, или даже пытаясь отправить данные. Это, вероятно, истечет время ожидания, но это не может быть хорошо спланировано. (Должно быть, для приличной СУБД, но может и не быть.) Поэтому, в зависимости от вашей СУБД, вам может потребоваться предпринять некоторые шаги, чтобы сообщить серверу, что вы отключаетесь, чтобы он освободил свои ресурсы.

1 голос
/ 07 июня 2009

В C # неявная очистка выполняется сборщиком мусора, если в объекте, собираемом мусором, реализован финализатор. Любую очистку неуправляемых ресурсов, таких как соединения с базой данных, можно выполнить методом Dispose.

См. Эту статью для получения дополнительной информации:

Реализация финализации и утилизация для очистки неуправляемых ресурсов
http://msdn.microsoft.com/en-us/library/b1yfkh5e(VS.71).aspx

0 голосов
/ 07 июня 2009

В C # вы обычно закрываете соединения сразу после их использования, например ::

using(SqlConnection connection = ...)
{
   ... do something ...
} // connection disposed / closed here

Однако, как правило, вы будете использовать пул соединений, и все, что он делает - возвращает соединение с пулом. Таким образом, ваш процесс все еще будет иметь активные подключения к серверу базы данных.

Если вы корректно завершите работу, пул соединений, несомненно, будет очищен, и фактические соединения с базой данных будут закрыты (вы можете убедиться в этом, просмотрев открытые соединения на сервере базы данных).

Но существуют ситуации (например, вызов Environment.FailFast), когда приложение может аварийно завершить работу, не закрывая соединения - в этом случае они в конечном итоге прекратят работу и будут закрыты сервером базы данных.

0 голосов
/ 07 июня 2009

Общее поведение POSIX заключается в том, что после завершения программы все файловые дескрипторы, сетевые подключения и т. Д. Закрываются. Правильно ли делает другой конец в этот момент - открытый вопрос, но если вы используете какую-либо достаточно популярную СУБД, все будет в порядке.

0 голосов
/ 07 июня 2009

Это должно быть очищено на следующем GC, но если быть точным, в C # вы можете закрыть соединение в блоке finally обработки структурированных исключений.

try {
  // open DB connection
} catch (Exception ex) {
  // deal with exception
} finally {
  // close and dispose connection
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...