private void CleanupReaderOnError(SQLiteDataReaderWrapper dr, SqliteConnection conn, SqliteCommand command) { TransactionContext context = TransactionContext.Current; if (dr != null) { if (!dr.IsClosed) { dr.Close(); } if (!dr.IsDisposed) { DataReader_Disposed(dr, new DataReaderDisposedEventArgs(conn, context, command)); return; } } if (command != null && context != null) { context.ReleaseConnection(); } if (command != null) { command.Dispose(); } }
public override IDataReader ExecuteReader(string commandText, params DbParam [] parameters) { SqliteConnection conn = null; SqliteCommand command = null; SQLiteDataReaderWrapper dr = null; DateTime start = DateTime.Now; bool isReadOnly = false; bool retry; DateTime end = DateTime.Now.AddMilliseconds(BUSY_TIMEOUT); do { retry = false; try { command = GetCommand(out conn, commandText, parameters, out isReadOnly); //create a reader SqliteDataReader reader = command.ExecuteReader(); if (reader == null) { throw new DbConnectionLostException("Could not get a valid reader from the database"); } dr = new SQLiteDataReaderWrapper(conn, TransactionContext.Current, reader, command); dr.Disposed += DataReader_Disposed; // detach the SqlParameters from the command object, so they can be used again. command.Parameters.Clear(); } catch (SqliteException ex) { CleanupReaderOnError(dr, conn, command); if ((ex.ErrorCode == SQLiteErrorCode.Busy || ex.ErrorCode == SQLiteErrorCode.Locked) && end < DateTime.Now) { retry = true; Thread.Sleep(BUSY_SLEEP); } else if (ex.InnerException is TargetInvocationException) { throw new DbConnectionLostException(ex); } else { throw; } } catch (DbConnectionLostException) { CleanupReaderOnError(dr, conn, command); throw; } catch { CleanupReaderOnError(dr, conn, command); } finally { OnCommandExecuted(commandText, start, parameters, isReadOnly); } } while (retry); return(dr); }