Невозможно выполнить команду SQL в службе Windows - PullRequest
1 голос
/ 30 июня 2011

Я работаю над созданием службы Windows, которая будет отправлять электронные письма клиенту, когда срок его отправки истекает в течение месяца. Я использую vb.net в Visual Studios 2008

Поскольку это служба Windows, ее очень сложно отлаживать. Пытаясь сузить свою ошибку, я создал метод sendDebugEmail, который отправляет мне электронное письмо, если оно попадает на определенную строку. Письма никогда не проходят мимо "dr = cmd.ExecuteReader ()"

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

Я создал базу данных dummy_database, которую я только что создал на сервере sql. Я добавил оператор INSERT sql для фиктивной таблицы, которая у меня есть, просто чтобы посмотреть, смогу ли я получить доступ к базе данных. Все, что принимает таблица, это номер строки и время ее отправки. Когда я запускаю службу Windows, база данных обновляется очень хорошо.

Любая помощь будет оценена. Спасибо

Dim conn As New SqlConnection(connString2)

    sendDebugEmail("134")

    SQL = "Select email FROM _Customer WHERE custID in (SELECT custID FROM _OnlineCustomer WHERE ExpirationDate <= '6-20-12' AND ExpirationDate >= '6-10-12')"
    Dim cmd As New SqlCommand(SQL, conn)


    sSubject = "hello"
    sBody = "This is test data"
    Dim dr As SqlDataReader

    sendDebugEmail("143")

    Try
        dr = cmd.ExecuteReader()   // This is were it stops

        sendDebugEmail("147")

        While dr.Read

            sendDebugEmail("152")

            Try
                LogInfo("Service woke up")
                Dim i As Integer = 0
                ' Prepare e-mail fields
                sFrom = "test@gmail.com"
                sTo = "test1@gmail.com"
                sCc = "test2@gmail.com"
                Dim oMailMsg As MailMessage = New MailMessage
                oMailMsg.From = sFrom
                oMailMsg.To = sTo
                oMailMsg.Cc = sCc
                ' Call a stored procedure to process the current item
                ' The success message
                oMailMsg.Subject = sSubject + "(Success)"
                oMailMsg.Body = sBody + "Email has been sent successfully."
                ' Send the message
                If Not (oMailMsg.To = String.Empty) Then
                    SmtpMail.Send(oMailMsg)
                End If

            Catch obug As Exception
                LogEvent(obug.Message)
            Finally

            End Try
        End While
    Catch ex As Exception

    Finally
        dr.Close()
        cmd.Dispose()
        conn.Close()
        conn.Dispose()
    End Try
End Sub

/////////////////////////////////////////////// //////////////////////////////////

Проблема решена: Я установил соединение, но никогда не открывал его.
Мне нужно conn.open ()

Больше всего мне помогло добавление этого кода в мой последний оператор catch:

sendDebugEmail(ex.Message & vbcrlf & ex.stackTrace)

Он отправил мне электронное письмо от stackTrace и упростил отладку

Ответы [ 4 ]

2 голосов
/ 30 июня 2011

Вы ловите и глотаете исключения? Если да, остановись. Пусть служба исключений аварийно завершает работу службы: исключение будет зарегистрировано в журнале событий. Единственные исключения, которые вы должны перехватить, - это те, из которых вы действительно можете восстановиться (хотя допустимо перехватить исключение, зарегистрировать его и повторно выбросить с помощью throw;).

Вы указали в своем коде log4net (http://logging.apache.org/log4net/), или что-то подобное?) Должно быть, особенно для демона, такого как служба Windows, - как иначе вы (или операции) собираетесь диагностировать проблемы со службой, когда происходит (как они будут).

Отредактировано на заметку:

  1. Вы должны использовать операторы using: все эти объекты ADO.Net имеют значение IDisposable. Это делает для более чистого кода.

  2. Рассмотрите возможность использования SqlDataAdapter для заполнения DataTable или DataSet вашим набором результатов. Шаблон, который вы используете:

    read a row from SQL
    while read was successful
      send an email
      read a row from SQL
    

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

1 голос
/ 01 июля 2011

Если вы уверены в своем коде (без исключений), я думаю, вы должны проверить аутентификацию, которую вы используете для подключения к SQL-серверу (внутри строки подключения в файле app.config / встроенном коде услуги windows).

Если вы используете для этого аутентификацию SQL (проверьте строку подключения для имени пользователя sa и его пароля), вам поможет настройка типа учетной записи службы Windows на LocalService .

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

Изменение типа учетной записи может быть выполнено и после установки. Для этого перейдите в Панель управления-> Администрирование-> Службы-> YourService , щелкните правой кнопкой мыши и выберите Propertes-> Logon и выполните его там. Если вы выбираете LocalSystem (проверка подлинности Windows), вам будет предложено ввести учетные данные для входа в учетную запись, в которой работает служба.

В случае проверки подлинности Windows в соединении SQL учетные данные учетной записи, в которой работает служба, будут также приниматься за соединение SQL.

Надеюсь, это поможет ...

0 голосов
/ 15 июня 2012

Проблема решена: Я установил соединение, но никогда не открывал его.
Мне нужен conn.open ()

Больше всего мне помогло добавление этого кода вмой последний оператор catch:

sendDebugEmail(ex.Message & vbcrlf & ex.stackTrace)

Он отправил мне электронное письмо от stackTrace и упростил отладку

0 голосов
/ 01 июля 2011

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...