NOTA: Se houver uma pergunta semelhante, por favor , encaminhe-me para ela.
Eu tenho duas tabelas Request
& Receipt
.
Eu quero que a tabela Receipt
permaneça bloqueada para operações CRUD de qualquer lugar até que a transação seja concluída. Eu preciso que a transação esteja em um procedimento armazenado.
É impossível? Como?
Por que deve Receipt
permanecer bloqueado?
Porque uma solicitação interna de inserção ou exclusão Receipt
não poderá manipulá-la! Observe que eu preciso ReceiptId
ser consecutivo por cada um Request
de seu start
para seu finish
!
Use uma tabela de chaves para alocar números de recibos de uma maneira que seja amigável à simultaneidade e ainda garanta que os números de recibos nunca serão reutilizados e (quase) nunca conterão lacunas.
Eu criei um exemplo verificável minimamente completo que você pode usar como base para aprender sobre simultaneidade que deve colocá-lo em um bom caminho.
Faça este trabalho em tempdb para que não matemos nada importante em seu trabalho real:
Se os objetos que estamos criando já existirem, vamos excluí-los primeiro. Isso nos permite modificar facilmente o código abaixo e executá-lo várias vezes para teste.
Tabela de solicitações - adicione colunas conforme necessário:
Tabela de recibos. ReceiptID é gerado pelo sistema, ReceiptNum é o número que mostraremos aos usuários.
A tabela Key, onde armazenamos o valor ReceiptNum alocado mais recentemente:
O procedimento armazenado CreateRequests:
Aqui, adicionamos três solicitações diferentes, com um número variável de recibos para mostrar a funcionalidade do procedimento armazenado:
A saída:
Execução nº 2:
A saída:
Execução nº 3:
A saída:
Para verificar a simultaneidade e se a alocação de números de recibo é confiável, executei o seguinte código simultaneamente em três janelas SSMS separadas, criando quase 30.000 recibos:
Não tenho certeza sobre o travamento apropriado. mas você pode descobrir se a tabela está bloqueada