2011-07-21 17 views
7

Estoy trabajando en una aplicación multiproceso que utiliza DB2 para su base de datos primaria. En el pasado, utilizamos principalmente columnas de identidad para las tablas en las que necesitábamos un identificador único generado automáticamente. Para ello se correría el siguiente 2 consultas en la misma transacción:Cómo obtener un valor de secuencia de DB2 en una aplicación multiproceso

INSERT INTO tbname (IDENTITY_COL, ...) VALUES (DEFAULT, ...); 
SELECT IDENTITY_VAL_LOCAL() FROM SYSIBM.SYSDUMMY1; 

Nosotros ahora están siendo presionados para cambiar a la secuencia en su lugar. Sé que puede usar "VALOR PRÓXIMO PARA colname" en las instrucciones INSERT y SELECT, pero no entiendo cómo INSERTAR y SELECCIONAR con el mismo valor sin arriesgar una condición de carrera en una aplicación multiproceso. Por ejemplo, si uso:

INSERT INTO tbname (SEQUENCE_COL, ...) VALUES (NEXT VALUE FOR SEQUENCE_COL, ...); 
SELECT PREVIOUS VALUE FOR SEQUENCE_COL; 

Entonces existe la posibilidad de otro inserto se llevó a cabo entre el inserto y SELECT anterior, por lo tanto, me proporciona el valor incorrecto. Si trato:

SELECT NEXT VALUE FOR SEQUENCE_COL; 

tienda el valor de una variable y pasar de que en el prospecto:

INSERT INTO tbname (SEQUENCE_COL, ...) VALUES (variable_value, ...); 

A continuación, hay una posibilidad de que otro hilo tiene el mismo NEXT VALUE y trata de insertar el mismo valor , lo que da como resultado un error DB2 -803. ¿Es posible usar columnas de SECUENCIA en un entorno multiproceso, o tengo que pelear para mantener mis columnas de IDENTIDAD?

Respuesta

6

Además de lo que Michael Sharek (correctamente) dijo:

INSERT INTO tbname (SEQUENCE_COL, ...) VALUES (NEXT VALUE FOR SEQUENCE_COL, ...); 
SELECT PREVIOUS VALUE FOR SEQUENCE_COL; 

Su hipótesis Entonces existe la posibilidad de otro inserto se llevó a cabo entre el inserto y SELECT anterior, por lo tanto, me proporciona el valor incorrecto "con respecto a la la secuencia de declaraciones anterior es incorrecta.

El "valor próximo" y "valor anterior" son conexión específica.

acceso a una secuencia de diferentes hilos nunca se va a crear una "carrera" condición. Cada conexión tiene un "entorno" completamente aislado para la secuencia.

+0

Muchas gracias por proporcionarnos la aclaración específica de la conexión. Exactamente lo que necesitaba escuchar. –

6

Tiene una suposición equivocada en su pregunta.

si trato:

SELECT NEXT VALUE FOR SEQUENCE_COL; 

tienda el valor de una variable y pasar de que en el prospecto:

INSERT INTO tbname (SEQUENCE_COL, ...) VALUES (variable_value, ...); 

Entonces hay una posibilidad otro hilo obtuvo el mismo VALOR PRÓXIMO e intenta i inserte el mismo valor

Eso no es correcto. El segundo hilo obtendría un NEXTVAL diferente y no el mismo valor que el primer hilo.

También quiero añadir mi opinión sobre esta parte:

Nosotros ahora están siendo presionados para cambiar a la secuencia en su lugar.

No puedo imaginar que haya una buena razón para cambiar a secuencias de identidad. Básicamente son lo mismo.

+0

Gracias por la respuesta. La aclaración de la seguridad de conexión proporcionada por a_horse_with_no_name me permite comprender mejor por qué está bien, pero ambas respuestas me ayudaron mucho. En cuanto a la presión, que es a perder parte de la sobrecarga en las identidades y dar a los programadores más rienda sobre cómo se establecen estas columnas (alto nivel de explicación). –

2

Además de las otras respuestas correctas, también puede simplemente usar una sola instrucción para insertar una fila y devolver valores insertados de la siguiente manera:

SELECT SEQUENCE_COL FROM NEW TABLE (
    INSERT INTO tbname (SEQUENCE_COL, ...) VALUES (NEXT VALUE FOR MY_SEQUENCE, ...) 
) 
Cuestiones relacionadas