Столбец идентификатора SQL Server, кажется, сбрасывается в приложении C # - PullRequest
0 голосов
/ 07 мая 2018

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

Приложение, используемое моей организацией, является пользовательским приложением C #. Я копался в журналах и выделил проблему в таблицу, которая отслеживает сеансы пользователей.

NHibernate.Exceptions.GenericADOException: не удалось выполнить пакетную команду. [SQL: SQL недоступен] ---> System.Data.SqlClient.SqlException: Нарушение ограничения PRIMARY KEY 'PK__tUserSes__3214EC07F91B0D0B'. Невозможно вставить дубликат ключа в объект 'SiteUser.tUserSession'. Значение дубликата ключа (7062).

В этой таблице более 300000 записей, и идентификатор явно неверный, это не тот идентификатор, который должен быть. Чем больше я возвращаюсь в журналах, тем ниже номер Id. Как будто в некоторых случаях счетчик идентификаторов был отдохнувшим.

Всякий раз, когда я пытаюсь добавить новую запись, я получаю сообщение «Произошла системная ошибка во время обработки запроса. Пожалуйста, свяжитесь с системным администратором». который в логах выглядит как Невозможно вставить дубликат ключа в объект 'SiteUser.tUserSession'. Дубликат значения ключа (7062).

Я отследил журналы до точки, где ошибка появилась впервые. Это было на самом деле в начале файла журнала за день 20180507.log

2018-05-07 00: 24: 29,990 WARN NHibernate.Util.ADOExceptionReporter - System.Data.SqlClient.SqlException (0x80131904): истекло время ожидания. Время ожидания истекло до завершения операции или сервер не отвечает.

System.ComponentModel.Win32Exception (0x80004005): Тайм-аут операции ожидания

at System.Data.SqlClient.SqlConnection.OnError (исключение SqlException, логическое breakConnection, действие`1 wrapCloseInAction)
в System.Data.SqlClient.TdsParser.ThrowExceptionAndWarning (TdsParserStateObject stateObj, логический вызывающий объектHasConnectionLock, логический асинхронныйClose)
в System.Data.SqlClient.TdsParser.TryRun (RunBehavior runBehavior, SqlCommand cmdHandler, SqlDataReader dataStream, BulkCopySimpleResultSet bulkCopyHandler, TdsParserStateObject stateObj, data_22Ready, Boolean) at System.Data.SqlClient.TdsParser.Run (RunBehavior runBehavior, SqlCommand cmdHandler, SqlDataReader dataStream, BulkCopySimpleResultSet bulkCopyHandler, TdsParserStateObject stateObj)
в System.Data.SqlClient.TdsParser.TdsExecuteTransactionManagerRequest (буфер Byte [], запрос TransactionManagerRequestType, строковое имя транзакции, TransactionManagerIsolationLevel isoLevel, тайм-аут Int32, транзакция SqlInternalTransaction, состояние 10jbBlayer) в System.Data.SqlClient.SqlInternalConnectionTds.ExecuteTransactionYukon (TransactionRequest транзакцияRequest, строковое имя транзакции, IsolationLevel iso, внутренняя транзакция SqlInternalTransaction, логическое значение isDelegateControlRequest)
в System.Data.SqlClient.SqlInternalTransaction.Commit ()
в System.Data.SqlClient.SqlTransaction.Commit ()
в NHibernate.Transaction.AdoNetTransactionFactory.ExecuteWorkInIsolation (сеанс ISessionImplementor, работа IIsolatedWork, логическая транзакция)

ClientConnectionId: c6788280-f7cc-4c3a-9bf2-514f4df84fc9
Номер ошибки: -2, состояние: 0, класс: 11
2018-05-07 00: 24: 30,006 ОШИБКА NHibernate.Util.ADOExceptionReporter - Истекло время ожидания. Время ожидания истекло до завершения операции или сервер не отвечает.
2018-05-07 00: 24: 30,006 WARN NHibernate.Util.ADOExceptionReporter - System.ComponentModel.Win32Exception (0x80004005): Время ожидания операции ожидания истекло
2018-05-07 00: 24: 30,006 ОШИБКА NHibernate.Util.ADOExceptionReporter - Тайм-аут операции ожидания
2018-05-07 00: 24: 30,006 ОШИБКА NHibernate.Base.Transaction.With - транзакция не выполнена.
NHibernate.Exceptions.GenericADOException: ошибка при выполнении изолированной работы [SQL: SQL недоступен] ---> System.Data.SqlClient.SqlException: истекло время ожидания. Время ожидания истекло до завершения операции или сервер не отвечает. ---> System.ComponentModel.Win32Exception: истекло время ожидания операции ожидания
--- Конец внутренней трассировки стека исключений ---
в System.Data.SqlClient.SqlConnection.OnError (исключение SqlException, логическое breakConnection, действие 1 wrapCloseInAction)<br> at System.Data.SqlClient.TdsParser.ThrowExceptionAndWarning(TdsParserStateObject stateObj, Boolean callerHasConnectionLock, Boolean asyncClose)<br> at System.Data.SqlClient.TdsParser.TryRun(RunBehavior runBehavior, SqlCommand cmdHandler, SqlDataReader dataStream, BulkCopySimpleResultSet bulkCopyHandler, TdsParserStateObject stateObj, Boolean& dataReady)<br> at System.Data.SqlClient.TdsParser.Run(RunBehavior runBehavior, SqlCommand cmdHandler, SqlDataReader dataStream, BulkCopySimpleResultSet bulkCopyHandler, TdsParserStateObject stateObj)<br> at System.Data.SqlClient.TdsParser.TdsExecuteTransactionManagerRequest(Byte[] buffer, TransactionManagerRequestType request, String transactionName, TransactionManagerIsolationLevel isoLevel, Int32 timeout, SqlInternalTransaction transaction, TdsParserStateObject stateObj, Boolean isDelegateControlRequest)<br> at System.Data.SqlClient.SqlInternalConnectionTds.ExecuteTransactionYukon(TransactionRequest transactionRequest, String transactionName, IsolationLevel iso, SqlInternalTransaction internalTransaction, Boolean isDelegateControlRequest)<br> at System.Data.SqlClient.SqlInternalTransaction.Commit()<br> at System.Data.SqlClient.SqlTransaction.Commit()<br> at NHibernate.Transaction.AdoNetTransactionFactory.ExecuteWorkInIsolation(ISessionImplementor session, IIsolatedWork work, Boolean transacted)<br> --- End of inner exception stack trace ---<br> at NHibernate.Transaction.AdoNetTransactionFactory.ExecuteWorkInIsolation(ISessionImplementor session, IIsolatedWork work, Boolean transacted) at NHibernate.Transaction.AdoNetWithDistributedTransactionFactory.ExecuteWorkInIsolation(ISessionImplementor session, IIsolatedWork work, Boolean transacted) at NHibernate.Engine.TransactionHelper.DoWorkInNewTransaction(ISessionImplementor session) at NHibernate.Id.MultipleHiLoPerTableGenerator.Generate(ISessionImplementor session, Object obj) at NHibernate.Event.Default.AbstractSaveEventListener.SaveWithGeneratedId(Object entity, String entityName, Object anything, IEventSource source, Boolean requiresImmediateIdAccess) at NHibernate.Event.Default.DefaultSaveOrUpdateEventListener.SaveWithGeneratedOrRequestedId(SaveOrUpdateEvent event) at NHibernate.Event.Default.DefaultSaveOrUpdateEventListener.EntityIsTransient(SaveOrUpdateEvent event) at NHibernate.Event.Default.DefaultSaveOrUpdateEventListener.OnSaveOrUpdate(SaveOrUpdateEvent event) at NHibernate.Impl.SessionImpl.FireSaveOrUpdate(SaveOrUpdateEvent event) at NHibernate.Impl.SessionImpl.SaveOrUpdate(Object obj) at Quiddita.Business.Statistics.Services.StatisticsBusinessService.<>c__DisplayClass1.<CreateNewUserSession>b__0() in d:\Projects\CAT – Site Database\Source\Quiddita.Business.Statistics\Services\StatisticsBusinessService.cs:line 71 at NHibernate.Base.Transaction.With.Transaction(IsolationLevel level, Action transactional) in d:\Projects\CAT – Site Database\Source\NHibernate.Base\Transaction\With.Transaction.cs:line 39 2018-05-07 00:24:30,037 ERROR Quiddita.Aspects.Statistics.MethodBoundaryAspects.NewSessionAspectAttribute - NewSessionAspectAttribute.OnSuccess failed to execute. NHibernate.Exceptions.GenericADOException: error performing isolated work[SQL: SQL not available] ---> System.Data.SqlClient.SqlException: Timeout expired. The timeout period elapsed prior to completion of the operation or the server is not responding. ---> System.ComponentModel.Win32Exception: The wait operation timed out --- End of inner exception stack trace --- at System.Data.SqlClient.SqlConnection.OnError(SqlException exception, Boolean breakConnection, Action 1 wrapCloseInAction) в System.Data.SqlClient.TdsParser.ThrowExceptionAndWarning (TdsParserStateObject stateObj, логический callerHasConnectionLock, логический asyncClose) в System.Data.SqlClient.TdsParser.TryRun (RunBehavior runBehavior, SqlCommand cmdHandler, SqlDataReader dataStream, BulkCopySimpleResultSet bulkCopyHandler, TdsParserStateObject stateObj, Boolean) в System.Data.SqlClient.TdsParser.Run (RunBehavior runBehavior, SqlCommand cmdHandler, SqlDataReader dataStream, BulkCopySimpleResultSet bulkCopyHandler, TdsParserStateObject stateObj) в System.Data.SqlClient.TdsParser.TdsExecuteTransactionManagerRequest (буфер Byte [], запрос TransactionManagerRequestType, строковое имя транзакции, TransactionManagerIsolationLevel isoLevel, тайм-аут Int32, транзакция SqlInternalTransaction, состояние объекта-объекта-объекта-транзакции) в System.Data.SqlClient.SqlInternalConnectionTds.ExecuteTransactionYukon (TransactionRequest транзакцияRequest, строковое имя транзакции, IsolationLevel iso, внутренняя транзакция SqlInternalTransaction, логическое значение isDelegateControlRequest) в System.Data.SqlClient.SqlInternalTransaction.Commit () в System.Data.SqlClient.SqlTransaction.Commit () в NHibernate.Transaction.AdoNetTransactionFactory.ExecuteWorkInIsolation (сеанс ISessionImplementor, работа IIsolatedWork, транзакция Boolean) --- Конец внутренней трассировки стека исключений --- в NHibernate.Transaction.AdoNetTransactionFactory.ExecuteWorkInIsolation (сеанс ISessionImplementor, работа IIsolatedWork, транзакция Boolean) в NHibernate.Transaction.AdoNetWithDistributedTransactionFactory.ExecuteWorkInIsolation (сеанс ISessionImplementor, работа IIsolatedWork, логическая транзакция) в NHibernate.Engine.TransactionHelper.DoWorkInNewTransaction (сеанс ISessionImplementor) в NHibernate.Id.MultipleHiLoPerTableGenerator.Generate (сеанс ISessionImplementor, объектный объект) в NHibernate.Event.Default.AbstractSaveEventListener.SaveWithGeneratedId (Объектный объект, String entityName, Любой объект, Источник IEventSource, Boolean requireImmediateIdAccess) в NHibernate.Event.Default.DefaultSaveOrUpdateEventListener.SaveWithGeneratedOrRequestedId (событие SaveOrUpdateEvent) в NHibernate.Event.Default.DefaultSaveOrUpdateEventListener.EntityIsTransient (событие SaveOrUpdateEvent) в NHibernate.Event.Default.DefaultSaveOrUpdateEventListener.OnSaveOrUpdate (событие SaveOrUpdateEvent) в NHibernate.Impl.SessionImpl.FireSaveOrUpdate (событие SaveOrUpdateEvent) в NHibernate.Impl.SessionImpl.SaveOrUpdate (Object obj) на Quiddita.Business.Statistics.Services.StatisticsBusinessService. <> c__DisplayClass1.b__0 () в d: \ Projects \ CAT - База данных сайта \ Source \ Quiddita.Business.Statistics \ Services \ StatisticsBusinessService.cs: строка 71 на NHibernate.Base.Transaction.With.Transaction (уровень IsolationLevel, транзакционный Action) в d: \ Projects \ CAT - База данных сайта \ Source \ NHibernate.Base \ Transaction \ With.Transaction.cs: строка 54 на Quiddita.Business.Statistics.Services.StatisticsBusinessService.CreateNewUserSession (Nullable 1 userId, String IPAddress) in d:\Projects\CAT – Site Database\Source\Quiddita.Business.Statistics\Services\StatisticsBusinessService.cs:line 74 at Quiddita.Aspects.Statistics.MethodBoundaryAspects.NewSessionAspectAttribute.OnSuccess(MethodExecutionArgs args) in d:\Projects\CAT – Site Database\Source\Quiddita.Aspects.Statistics\MethodBoundaryAspects\NewSessionAspectAttribute.cs:line 68 2018-05-07 00:24:31,056 WARN NHibernate.Util.ADOExceptionReporter - System.Data.SqlClient.SqlException (0x80131904): Violation of PRIMARY KEY constraint 'PK__tUserSes__3214EC07F91B0D0B'. Cannot insert duplicate key in object 'SiteUser.tUserSession'. The duplicate key value is (1). The statement has been terminated. at System.Data.SqlClient.SqlConnection.OnError(SqlException exception, Boolean breakConnection, Action 1 wrapCloseInAction) в System.Data.SqlClient.TdsParser.ThrowExceptionAndWarning (TdsParserStateObject stateObj, логический callerHasConnectionLock, логический asyncClose)в System.Data.SqlClient.TdsParser.TryRun (RunBehavior runBehavior, SqlCommand cmdHandler, SqlDataReader dataStream, BulkCopySimpleResultSet bulkCopyHandler, TdsParserStateObject stateObj, данные Boolean) в System.Data.SqlClient.SqlCommand.FinishExecuteReader (SqlDataReader ds, RunBehavior runBehavior, String resetOptionsString) в System.Data.SqlClient.SqlCommand.RunExecuteReaderTds (CommandBehavior cmdBehavior, RunBehavior runBehavior, логический returnStream, логический асинхронный, тайм-аут Int32, задача и задача, логический асинхронный ввод, SqlDataReader) в System.Data.SqlClient.SqlCommand.RunExecuteReader (CommandBehavior cmdBehavior, RunBehavior runBehavior, логический returnStream, метод String, TaskCompletionSource 1 completion, Int32 timeout, Task& task, Boolean asyncWrite) at System.Data.SqlClient.SqlCommand.InternalExecuteNonQuery(TaskCompletionSource 1 завершение, строковый метод MethodName, логическое время sendToPrite, время3232) в System.Data.SqlClient.SqlCommand.ExecuteNonQuery () в System.Data.SqlClient.SqlCommandSet.ExecuteNonQuery () в NHibernate.AdoNet.SqlClientBatchingBatcher.DoExecuteBatch (IDbCommand ps) ClientConnectionId: a7af4119-1d67-4f69-ae91-fc556c97768f Номер ошибки: 2627, состояние: 1, класс: 14 2018-05-07 00: 24: 31,068 ОШИБКА NHibernate.Util.ADOExceptionReporter - Нарушение ограничения PRIMARY KEY 'PK__tUserSes__3214EC07F91B0D0B'. Невозможно вставить дубликат ключа в объект 'SiteUser.tUserSession'. Значение дубликата ключа (1). Заявление было прекращено. 2018-05-07 00: 24: 31,068 ОШИБКА NHibernate.Event.Default.AbstractFlushingEventListener - Не удалось синхронизировать состояние базы данных с сеансом NHibernate.Exceptions.GenericADOException: не удалось выполнить пакетную команду. [SQL: SQL недоступен] ---> System.Data.SqlClient.SqlException: Нарушение ограничения PRIMARY KEY 'PK__tUserSes__3214EC07F91B0D0B'. Невозможно вставить дубликат ключа в объект 'SiteUser.tUserSession'. Значение дубликата ключа (1). Заявление было прекращено. в System.Data.SqlClient.SqlConnection.OnError (исключение SqlException, логическое breakConnection, завершение действия 1 wrapCloseInAction) at System.Data.SqlClient.TdsParser.ThrowExceptionAndWarning(TdsParserStateObject stateObj, Boolean callerHasConnectionLock, Boolean asyncClose) at System.Data.SqlClient.TdsParser.TryRun(RunBehavior runBehavior, SqlCommand cmdHandler, SqlDataReader dataStream, BulkCopySimpleResultSet bulkCopyHandler, TdsParserStateObject stateObj, Boolean& dataReady) at System.Data.SqlClient.SqlCommand.FinishExecuteReader(SqlDataReader ds, RunBehavior runBehavior, String resetOptionsString) at System.Data.SqlClient.SqlCommand.RunExecuteReaderTds(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, Boolean async, Int32 timeout, Task& task, Boolean asyncWrite, SqlDataReader ds) at System.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, String method, TaskCompletionSource 1, тайм-аут Int32, задача и задача, логическое asyncWrite) в System.Data.SqlClient.SqlCommand.InternalExecuteNonQuery (завершение TaskCompletionSource`1, String methodName, логическое sendToPipe, тайм-аут Int32, логическое asyncWrite) в System.Data.SqlClient.SqlCommand.ExecuteNonQuery () в System.Data.SqlClient.SqlCommandSet.ExecuteNonQuery () в NHibernate.AdoNet.SqlClientBatchingBatcher.DoExecuteBatch (IDbCommand ps) --- Конец внутренней трассировки стека исключений --- в NHibernate.AdoNet.SqlClientBatchingBatcher.DoExecuteBatch (IDbCommand ps) в NHibernate.AdoNet.AbstractBatcher.ExecuteBatchWithTiming (IDbCommand ps) в NHibernate.AdoNet.AbstractBatcher.ExecuteBatch () в NHibernate.Engine.ActionQueue.ExecuteActions () в NHibernate.Event.Default.AbstractFlushingEventListener.PerformExecutions (сеанс IEventSource) 2018-05-07 00: 24: 31,068 ОШИБКА NHibernate.Base.Transaction.With - транзакция не выполнена.

Это является частью StatisticsBusinessService.cs: строка 74

/// <summary>
/// Creates new <c>UserSession</c> and saves the object to database.
/// </summary>
/// <param name="userId">The database id of the<see cref="User"/> associated with the Session. If <c>null</c> then the anonymous user is in question.</param>
/// <param name="IPAddress">The IPAddress of the client machine the page was accessed from.</param>
/// <returns>The newly created <c>UserSession</c> object.</returns>
public UserSession CreateNewUserSession(long? userId, string IPAddress)
{
    UserSession userSession = null;
    With.Transaction(() =>
    {
        userSession = InitializeUserSession();
        if (userId.HasValue)
            userSession.User = _securityService.LoadUser(userId.Value, null);
        userSession.IPAddress = IPAddress;
        UnitOfWork.CurrentSession.SaveOrUpdate(userSession);
    });
    return userSession;
}

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

До возникновения проблемы к серверу Windows не обращались в течение нескольких недель. Файлы не были изменены, и база данных не была изменена. Окна не были обновлены. В основном ничего в системе не изменилось, но счетчик идентификаторов был каким-то образом сброшен. Я проверил базу данных, столбцы идентификаторов не были установлены в идентичность (ложь), поэтому я предполагаю, что автоинкремент был реализован в приложении, а не на уровне базы данных.

У меня 0 опыта работы с C #, SQL Server и всей экосистемой Windows. Я в полной растерянности происходящего.

Мы используем Windows Server 2012r2, SQL Server 2014 Express, IIS 8

Любая подсказка будет высоко ценится.

1 Ответ

0 голосов
/ 07 мая 2018

Какая трассировка стека!

Если я правильно понял, ваше семя автонумера только что восстановлено. Сделайте резервную копию и попробуйте это:

SELECT MAX(tUserSession) FROM SiteUser

У вас есть номер, скажем, 123456 затем повторно введите ваш автонуммер с тем же значением:

DBCC CHECKIDENT (SiteUser, RESEED, 123456)
...