Por que “Begin Transaction” antes de “Insert Query” bloquear a tabela inteira?

6

Eu escrevi um procedimento armazenado para inserir um registro. Eu adicionei "Begin Transaction" logo acima da Insert Query e executei a consulta. Percebi que outro aplicativo que mostrava uma página da Web com registros da mesma tabela, foi interrompido no momento em que a inserção foi concluída.

Por que começar a transação bloqueia a tabela inteira? Os escritores não devem bloquear os Leitores. Ele deve estar ativado por padrão.

Estou usando o SQL-Server 2005 Express. Eu também quero saber como o Oracle e o MySQL lidam com a mesma situação.

    
por RPK 30.09.2011 / 16:51

4 respostas

5

Begin Transaction é o início de uma transação - nenhum outro dado pode ser gravado na tabela até que você finalize sua transação, isso ocorre por design, para aplicar os critérios ACID no banco de dados. link

Você usa uma transação se precisar executar várias consultas como se fossem uma única operação atômica. Se você não precisa de atomicidade, não use transações!

No entanto, isso é muito básico - você pode precisar se atualizar sobre a teoria básica do banco de dados antes de tentar escrever código de banco de dados, você pode causar sérios danos a um aplicativo se não estiver familiarizado com os princípios básicos como transações.

    
por 30.09.2011 / 17:25
4

Embora o que os outros disseram seja basicamente correto, esse comportamento depende do nível de isolamento da transação que você está usando; é tecnicamente possível para uma transação não bloquear uma tabela inteira.

Se você quiser que outros usuários possam ler seus dados enquanto ainda os modifica, você pode definir o TIL como READ UNCOMMITED :

SET TRANSACTION ISOLATION LEVEL READ UNCOMMITED

É claro que você precisa ser muito cuidadoso com essa configuração, pois pode causar qualquer tipo de inconsistência de dados, dependendo do que outros usuários estão fazendo no momento.

Mais informações aqui:

link
link

    
por 30.09.2011 / 19:39
3

Bem, eu não sou um cara do SQL Server, então, não falarei sobre isso.

Mas, como a pergunta está marcada como 'oracle' e o pôster também perguntou como funciona no Oracle, vou abordar essa parte.

No Oracle, o nível de isolamento de transação padrão é READ COMMITTED. Além disso, o Oracle sempre é bloqueado no nível de linha e nunca encaminha um bloqueio para o nível de bloqueio (chamado de página no SQL Server?).

Portanto, se você bloquear a linha 'a' em uma tabela e outra sessão tentar bloquear a linha 'b' na mesma tabela, esse bloqueio será bem-sucedido, mesmo se as linhas estiverem em o mesmo bloco.

Quanto ao "início de uma transação", no Oracle, qualquer DML iniciará implicitamente uma transação, se ainda não tiver sido iniciada. Essa transação permanecerá aberta até que a sessão seja confirmada ou revertida explicitamente, ou seja, cancelada (nesse caso, o Oracle reverterá a transação).

No entanto, o Oracle tem uma sintaxe de "transação inicial", que é 'set transaction'. Isso pode ser usado para iniciar uma transação somente leitura ou leitura, ou para definir o nível de isolamento.

Um uso interessante de uma transação somente de leitura é que (além de ser somente leitura), ela fornece todas as consultas que são executadas nessa transação, leia a consistência até o ponto no tempo do início da transação. Assim, uma vez que você 'set transaction read only', qualquer consulta executada retornará resultados consistentes com a hora do início da transação. (Normalmente, os resultados da consulta são autoconsistentes com o ponto no tempo do início da execução da consulta, mas com uma transação somente leitura, todas as consultas executadas na transação serão consistentes com o início da transação.)

    
por 06.11.2011 / 23:21
1

Os escritores não devem bloquear os Leitores

Isso é válido apenas para isolamento de instantâneos , todos outros níveis de isolamento exigem que os dois leitores bloqueiem o bloqueador de escrita e os escritores para bloquear os leitores (leituras sujas não são consideradas, já que são inconsistent e nunca deve ser usado). Se você precisar desse comportamento, use o controle de versão de linha (o link contém a solução).

Por que a inserção em massa bloqueia a tabela inteira?

Isso, na verdade, pode ou não ser verdade. O comportamento está sob seu controle:

TABLOCK

Specifies that a table-level lock is acquired for the duration of the bulk-import operation. A table can be loaded concurrently by multiple clients if the table has no indexes and TABLOCK is specified. By default, locking behavior is determined by the table option table lock on bulk load.

Para mais detalhes, leia as especificações do produto: Controlando o comportamento de bloqueio para importação em massa .

    
por 30.09.2011 / 20:56