O problema é que onde você tem várias linhas sendo inseridas você está usando o mesmo próximo ID disponível para todas as linhas, você precisa adicionar
ROW_NUMBER()
in para garantir que o xid fosse exclusivo na inserção:insert into [xtable] (XID)
select [x].[NextavailableID] + ROW_NUMBER() OVER (ORDER BY i.ID)
from inserted [i]
cross apply
(
select coalesce(max([t].[XID]), 0) [NextavailableID]
from [xtable] [t] WITH (TABLOCK, HOLDLOCK)
) [x];
Com relação à prevenção de duplicatas, você pode usar dicas de tabela para bloquear
xtable
ao obter o máximo de xid
. A desvantagem de usar esses bloqueios é que você obterá um impasse. Você deve ter uma restrição/índice exclusivo nesta coluna, pois isso evitará duplicatas, mas também resultará em exceções quando uma condição de corrida for atendida. Em última análise, qualquer que seja o método escolhido, você precisará fazer algum tipo de sacrifício.