16

В настоящее время работает над приложением ASP.Net MVC 4 с использованием Entity Framework 5. Используется CodeFirst для начальной фазы разработки. Но теперь отключены автоматические миграции и проектирование новых таблиц напрямую с использованием SSMS и написания POCO. Все работает хорошо.База данных Windows Azure SQL - Identity Auto increment column пропускает значения

В последнее время выявлена ​​странная проблема в Production. Записи в одной из первоначально разработанных таблиц пропустили значение автоинкрементного значения более чем на 900 номеров. Это произошло 3 раза за последние 3 месяца. Отладка приложения локально, но не удалось воспроизвести. Наблюдается не какая-либо закономерность или тенденция.

Модель:

public class Enquiry 
{ 
    [Key] 
    [DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)] 
    public Int64 EnquiryId { get; set; } 

    [Required] 
    public int UserId { get; set; } 

    [Required] 
    public byte Bid { get; set; } 

    ... 

    [Required] 
    public DateTime Created { get; set; } 

    [Required] 
    public DateTime Modified { get; set; } 
} 

public class EnquiryDetail 
{ 
    [Key] 
    public Int64 EnquiryId { get; set; } 

    [Required] 
    public int CreditScore { get; set; } 

    [Required] 
    public byte BidMode { get; set; } 

    public virtual Enquiry Enquiry { get; set; } 
} 

DbContext:

public class EscrowDb : DbContext 
{ 

    public EscrowDb() 
     : base("name=DefaultConnection") 
    { 

    } 
    public DbSet<Enquiry> Enquiries { get; set; } 
    public DbSet<EnquiryDetail> EnquiryDetails { get; set; } 

    protected override void OnModelCreating(DbModelBuilder modelBuilder) 
    { 
     modelBuilder.Conventions.Remove<PluralizingTableNameConvention>(); 
     modelBuilder.Entity<EnquiryDetail>() 
      .HasRequired<Enquiry>(ed => ed.Enquiry) 
      .WithRequiredDependent(e => e.EnquiryDetail); 
    } 
} 

Контроллер:

[Authorize] 
public class EnquiryController : Controller 
{ 
    private EscrowDb _db = new EscrowDb(); 

    [HttpPost] 
    [ValidateAntiForgeryToken] 
    public ActionResult Create(EnquiryViewModel core) 
    { 
     var enquiry = new Enquiry(); 
     // Some code to set properties using passed ViewModel 
     ... 

     var enquiryDetail = new EnquiryDetail(); 
     // Some code to set properties using passed ViewModel 
     ... 

     enquiry.EnquiryDetail = enquiryDetail; 

     _db.Enquiries.Add(enquiry); 
     _db.SaveChanges(); 
    } 
} 

Все это код работает е до сих пор, за исключением того, что значение идентичности получалось пропущенным через большие промежутки почти 1000 чисел.

Неужели кто-нибудь сталкивался с такой проблемой? Пожалуйста, поделитесь своими мыслями.

+0

Посмотрите здесь: https://connect.microsoft.com/SQLServer/feedback/details/739013/alwayson-failover -results-in-reseed-of-identity –

+0

@Rosiek, я не вижу никакого хорошего готового к использованию решения там at может применяться к SQL Azure Web Edition в MS Cloud. – Santosh

+0

Я вижу ту же проблему. Любая удача в этом разобраться? –

ответ

18

Возможно, вам не повезло, если вам нужно устранить эти пробелы.

Я сам попал в эту проблему, поскольку я разрабатываю/тестирую новое приложение. Я интуитивно понимаю, что происходит здесь, в sql azure, основываясь на том, что я читал о SQL Server 2012. Я не смог найти документацию об этом для sql azure.

Из того, что я прочитал, это функция, которая встречается как ошибка ИМО. На сервере Sql 2012 Microsoft добавила возможность создавать последовательности. Последовательности записывают, какие значения использовались в блоках из 1000. Так что скажем, что ваша последовательность прогрессировала ... 1, 2, 3, 4, 5 ... и затем перезагружается ваш сервер sql. Ну, последовательность уже сохранила тот факт, что блок 1-1000 уже используется, поэтому он перескакивает на следующий 1000 .... так что ваше следующее значение 1001, 1002, 1003, 1004 .... Это улучшает производительность вставляет при использовании последовательностей, но может привести к необычным разрывам. Это решение для вашей последовательности. При указании вашей последовательности добавьте параметр «NOCACHE», чтобы он не сохранял блоки по 1000 за раз. See here for more documentation.

В этом случае проблема заключается в том, что столбцы Identity, похоже, были изменены для использования этой же парадигмы. Поэтому, когда ваш сервер или в этом случае перезагружается ваш экземпляр sql azure, вы можете получить большие пробелы (1000) в своих столбцах идентификации, поскольку он кэширует большие блоки как «используемые». Для сервера sql 2012 существует такое решение. Вы можете указать флаг запуска t272, чтобы вернуть вашу идентификационную информацию, используя парадигму старого сервера sql server 2008 r2. Проблема в том, что я не знаю (возможно, это невозможно) о том, как указать это в sql Azure. Не удается найти документацию. See this thread for more details on sql server 2012.

Check the documentation of identity here in the msdn. В частности раздел «Последовательные значения после перезапуска сервера или другие сбои».Вот что он говорит:

Последовательные значения после перезагрузки сервера или других сбоев -SQL сервера может кэшировать значения идентификаторов для повышения производительности, а некоторые из присвоенных значений могут быть потеряны в случае сбоя базы данных или сервера перезапуск. Это может привести к разрыву в значении идентификации при вставке. Если зазоры неприемлемы, то приложение должно использовать генератор последовательности с опцией NOCACHE или использовать собственный механизм для создания значений ключа .

Так что если вам нужно иметь последовательные значения, вы можете попробовать указать последовательность с nocache вместо того, чтобы полагаться на свой столбец идентичности. Не пробовал это сам, but sounds like you'll have trouble getting this to work with entity framework.

Извините, если это не поможет, но, по крайней мере, это информация о том, что вы переживаете.

0

Кажется, что TF 272 не работает вокруг SQL Azure. Я просто заметил проблему в двух таблицах (пробелы 999 и 1000) и подумал, что это нарушение безопасности, прежде чем проверять две таблицы и проверять вставленные записи. Для получения более подробной информации см. Последний пункт this MS TechNet discussion. Вид повторного подтверждения, но выглядит скорее как ошибка, чем функция.

0

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

1

Попробуйте пересадить с помощью спускового механизма. Я считаю, что это должно решить его example of its use и увидеть больше проходов по этой ссылке.

USE [TEST] 

CREATE TABLE TEST(ID INT IDENTITY(1,1),VAL VARCHAR(10)) 

CREATE TRIGGER TGR_TEST_IDENTITY ON TEST 
FOR INSERT 
AS 
DECLARE @RESEEDVAL INT 
SELECT @RESEEDVAL = MAX(ID) FROM TEST 
DBCC CHECKIDENT('TEST', RESEED, @RESEEDVAL) 

INSERT INTO TEST(VAL)VALUES('a') 

SELECT * FROM TEST 

С «DBCC CHECKIDENT» не поддерживается в Azure теперь вы можете использовать подход в этой link В этой связи я получил некоторые работы обходные

  1. Использование GUID в качестве ключа при использовании автоматического ключа ваш SqlAzure
  2. Если целочисленный ключ, как и мой случай, позволяет вставить запись и вернуться назад и удалить ее, а затем вставить ее правой клавишей с помощью Turing off identity с set identity_insert XXXTable on - это в основном отключает IDENTITY

, а затем поворачиваясь на идентичности еще раз, когда я через со вставкой с правой клавишей с помощью

набор IDENTITY_INSERT XXXTable от --this в основном включает ИДЕНТИЧНОСТИ

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

+0

Это волшебство для сервера, который часто перезагружается, и таблицы, которая редко получает строки! спасибо, были повсюду в interwebz, ища быстрый и грязный – user230910

+0

Приветствую вас, рад, что это было полезно для вас –