Оракул.Доступа к данным.Клиент.OracleException ORA-03135: соединение потеряно контакт

У меня есть служба .Net, которая подключается к базе данных Oracle по каждому запросу. Он отлично работает в начале, но после некоторого количества запросов я начинаю:

Oracle.DataAccess.Client.OracleException ORA-03135: connection lost contact
   at Oracle.DataAccess.Client.OracleException.HandleErrorHelper(Int32 errCode, OracleConnection conn, IntPtr opsErrCtx, OpoSqlValCtx* pOpoSqlValCtx, Object src, String procedure)
   at Oracle.DataAccess.Client.OracleException.HandleError(Int32 errCode, OracleConnection conn, String procedure, IntPtr opsErrCtx, OpoSqlValCtx* pOpoSqlValCtx, Object src)
   at Oracle.DataAccess.Client.OracleCommand.ExecuteReader(Boolean requery, Boolean fillRequest, CommandBehavior behavior)
   at Oracle.DataAccess.Client.OracleCommand.ExecuteReader()
   at MyApp.Services.OracleConnectionWithRetry.ExecuteReader(OracleCommand command)
   ...

есть идеи, в чем может быть проблема? Я распоряжаюсь всеми соединениями, результатами и параметрами. Нагрузка на эту службу, ну, очень низкая.

2 ответов


это происходит потому, что ваш код запрашивает соединение из пула соединений Oracle, и пул соединений возвращает отключенное / устаревшее соединение с БД Oracle. ODP.NET не проверяет состояние соединения, отправленного клиенту.

поэтому, чтобы быть в безопасности, либо вы проверяете connection status == Open для соединения, полученного из пула при выполнении соединения.Open ()

или

пусть ODP.NET сделайте проверку для вас, установив Validate Connection = true в строку подключения в web.конфиг.

оба этих метода влияют на производительность при тестировании состояния соединения при каждом подключении к базе данных.

третий вариант, который я использую является использование исключений. Сначала будьте оптимистичны и используйте соединение whateven, возвращаемое из пула соединений. Если вы получаете ORA-3135, то запросите новое соединение и выполните свой запрос снова, как цикл while. В лучшем случае, вы можете получить ваше 1st соединение как действительное и Ваше запрос будет выполнен. В худшем случае все соединения в вашем пуле устаревшие, и в этом случае код будет выполнен N раз (где N-размер пула соединений).


Я тоже это видел; попробуйте отключить пул соединений с "Pooling=false" в строке соединения. У меня есть теория, что бездействующие соединения в пуле истекают, но ODP.NET не понимает, что они истекли, а затем, когда ваше приложение захватывает один и пытается что-то сделать, вы получаете это исключение.