Sqlserver
 sql >> Baza danych >  >> RDS >> Sqlserver

Wybierz / wstaw wersję Upsert:czy istnieje wzorzec projektowy dla wysokiej współbieżności?

Możesz użyć LOCKS, aby rzeczy były SERIALIZOWANE, ale zmniejsza to współbieżność. Dlaczego nie wypróbować najpierw wspólnego warunku („głównie wstawiaj lub w większości wybierz”), a następnie bezpiecznej obsługi akcji „naprawczej”? To znaczy wzorzec „JFDI”...

Oczekiwane głównie INSERT (park piłki 70-80%+):

Po prostu spróbuj wstawić. Jeśli się nie powiedzie, wiersz został już utworzony. Nie musisz się martwić o współbieżność, ponieważ TRY/CATCH zajmuje się duplikatami za Ciebie.

BEGIN TRY
   INSERT Table VALUES (@Value)
   SELECT @id = SCOPE_IDENTITY()
END TRY
BEGIN CATCH
    IF ERROR_NUMBER() <> 2627
      RAISERROR etc
    ELSE -- only error was a dupe insert so must already have a row to select
      SELECT @id = RowID FROM Table WHERE RowValue = @VALUE
END CATCH

Głównie WYBRANE:

Podobnie, ale najpierw spróbuj uzyskać dane. Brak danych =WSTAWKA potrzebna. Ponownie, jeśli 2 równoczesne wywołania spróbują INSERT, ponieważ oba znalazły wiersz bez uchwytów TRY/CATCH.

BEGIN TRY
   SELECT @id = RowID FROM Table WHERE RowValue = @VALUE
   IF @@ROWCOUNT = 0
   BEGIN
       INSERT Table VALUES (@Value)
       SELECT @id = SCOPE_IDENTITY()
   END
END TRY
BEGIN CATCH
    IF ERROR_NUMBER() <> 2627
      RAISERROR etc
    ELSE
      SELECT @id = RowID FROM Table WHERE RowValue = @VALUE
END CATCH

Drugi wydaje się powtarzać, ale jest wysoce zbieżny. Blokady osiągnęłyby to samo, ale kosztem współbieżności...

Edycja:

Dlaczego nie aby użyć MERGE...

Jeśli użyjesz klauzuli OUTPUT, zwróci ona tylko to, co zostało zaktualizowane. Potrzebujesz więc fikcyjnej UPDATE, aby wygenerować tabelę INSERTED dla klauzuli OUTPUT. Jeśli musisz robić fałszywe aktualizacje z wieloma wywołaniami (jak sugeruje OP), to dużo zapisów w dzienniku tylko aby móc korzystać z funkcji MERGE.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Migawki bazy danych programu SQL Server -4

  2. Dynamiczne zapytanie PIVOT programu SQL Server?

  3. Zwróć klucze podstawowe z połączonego serwera w SQL Server (przykłady T-SQL)

  4. Data i godzina programu SQL Server PODOBNY wybór?

  5. Jak Operator w Entity Framework?