Problema com numero sequencial

6 respostas
Licuri

Galera preciso da ajuda de voces para resolver este problema.
Em um operação eu vou inserir mais de um linha, portanto adiciono em um bacth.

PreparedStatement stmt = con.prepareStatement(
"INSERT INTO Tabela VALUES (?, ?)");

id = getAutoIncrement("Tabela","id");

stmt.setInt(1, id);
stmt.setString(2, "Kelly Kaufmann");
stmt.addBatch();

stmt.setInt(1, id + 1);
stmt.setString(2, "Bill Barnes");
stmt.addBatch();

int[] updateCounts = stmt.executeBatch();

este método que getAutoIncrement faz um select na Tabela e pega o max do coluna id e soma 1.
O problema é: E se eu tiver mais de uma pessoa execundo este método de insert…?

6 Respostas

L

eu usaria um Select for Update no banco!
mas você tem a opção de usar um método ou um bloco de código synchronized!

[]s
Lucas Balensiefer

T
Ahá! Você descobriu porque é que os bancos de dados normalmente têm suporte a campos auto-numerados (ex.: SQL Server) ou a sequences (ex.: Oracle).

Essa história do max pode dar problemas mesmo.

(Bloco de dados synchronized não resolve o seu problema porque pode ser que outro programa é que esteja fazendo a inserção. Synchronized só ajuda se for uma outra thread do seu mesmo programa.)

(Esses problemas costumam dar no seu cliente, nunca em teste, e em ocasiões muito aleatórias - tipo em feriados - quando o seu celular, que você bobeou e deixou ligado, começa a tocar sem parar.)
_fs

É um problema ruim este.

O banco de dados que está usando não tem suporte built-in para este tipo de chave primária?

Caso contrário, há algumas soluções possíveis:
a. sincronizar o método: problemático. Se há vários clientes acessando o método, haverá lentidão.

b. criar uma classe “geradora de ids” que tem um buffer com X ids criados. O método getId() desta classe também é sincronizado, mas retorna sempre rapidamente.

Licuri
<blockquote><div class="quote-author">thingol:</div>Ahá! Você descobriu porque é que os bancos de dados normalmente têm suporte a campos auto-numerados (ex.: SQL Server) ou a “sequences” (ex.: Oracle).

Essa história do “max” pode dar problemas mesmo.

(Bloco de dados “synchronized” não resolve o seu problema porque pode ser que outro programa é que esteja fazendo a inserção. “Synchronized”  ajuda se for uma outra thread do seu mesmo programa.)

(Esses problemas costumam dar no seu cliente, nunca em teste, e em ocasiões muito aleatórias - tipo em feriados - quando o seu celular, que você bobeou e deixou ligado, começa a tocar sem parar.)</blockquote>

thingol então a solução é alterar esta minha coluna para auto númerica? Estou usando SQL-Server.

thingol mais se eu tiver que usar outro banco de dados?

Licuri

LIPE:

b. criar uma classe “geradora de ids” que tem um buffer com X ids criados. O método getId() desta classe também é sincronizado, mas retorna sempre rapidamente.

vc tem um exemplo?

1112
<blockquote><div class="quote-author">Licuri:</div><blockquote><div class="quote-author">thingol:</div>Ahá! Você descobriu porque é que os bancos de dados normalmente têm suporte a campos auto-numerados (ex.: SQL Server) ou a “sequences” (ex.: Oracle).

Essa história do “max” pode dar problemas mesmo.

(Bloco de dados “synchronized” não resolve o seu problema porque pode ser que outro programa é que esteja fazendo a inserção. “Synchronized”  ajuda se for uma outra thread do seu mesmo programa.)

(Esses problemas costumam dar no seu cliente, nunca em teste, e em ocasiões muito aleatórias - tipo em feriados - quando o seu celular, que você bobeou e deixou ligado, começa a tocar sem parar.)</blockquote>

thingol então a solução é alterar esta minha coluna para auto númerica? Estou usando SQL-Server.

thingol mais se eu tiver que usar outro banco de dados?

PostgreSQL suporta (através de sequences e do tipo de dados “Serial” (que nada mais é que um Integer associado a uma sequence)), Oracle suporta e SQL Server suporta. Não sei sobre outros mas, em último caso, você pode tentar fazer algum middle-tier.

Criado 28 de abril de 2006
Ultima resposta 28 de abr. de 2006
Respostas 6
Participantes 5