2012-04-05 20 views
13

Q1.: ¿Cuál es la diferencia entre la secuencia de la aplicación de identificación en una base de datos utilizando¿Cuál es la diferencia entre: ID de secuencia usando JPA @TableGenerator, @GeneratedValue vs base de datos Auto_Increment

A.

CREATE TABLE Person 
(
    id long NOT NULL AUTO_INCREMENT 
    ... 
    PRIMARY KEY (id) 
) 

frente

B.

@Entity 
public class Person { 
    @Id 
    @TableGenerator(name="TABLE_GEN", table="SEQUENCE_TABLE", pkColumnName="SEQ_NAME", 
     valueColumnName="SEQ_COUNT", pkColumnValue="PERSON_SEQ") 
    @GeneratedValue(strategy=GenerationType.TABLE, generator="TABLE_GEN") 
    private long id; 
    ... 
} 

Mi sistema es altamente concurrente. Dado que mi base de datos es un servidor Microsoft SQL, no creo que sea compatible con @SequenceGenerator, por lo que tengo que quedarme con @TableGenerator, que es propenso a problemas de concurrencia.

Q2. Este enlace aquí (http://en.wikibooks.org/wiki/Java_Persistence/Identity_and_Sequencing#Advanced_Sequencing) sugiere que B podría sufrir problemas de simultaneidad, pero no entiendo la solución propuesta. Le agradecería enormemente si alguien pudiera explicarme cómo evitar problemas de concurrencia con B. Aquí hay un fragmento de su solución:

If a large sequence pre-allocation size is used this becomes less of an issue, because the sequence table is rarely accessed.

Q2.1: ¿Cuánto tamaño de asignación estamos hablando aquí? ¿Debo hacer allocationSize=10 o allocationSize=100?

Some JPA providers use a separate (non-JTA) connection to allocate the sequence ids in, avoiding or limiting this issue. In this case, if you use a JTA data-source connection, it is important to also include a non-JTA data-source connection in your persistence.xml.

Q2.2: Consumo EclipseLink como el profesional; ¿Tengo que hacer lo que sugiere arriba?

Q3. Si B sufre problemas de simultaneidad, ¿A sufre lo mismo?

Respuesta

14

Usando un TableGenerator, el siguiente valor de identificación será buscado y mantenido en una tabla y mantenido básicamente por JPA y no por su base de datos. Esto puede generar problemas de simultaneidad cuando tiene varios subprocesos accediendo a su base de datos y tratando de averiguar cuál puede ser el siguiente valor para el campo de id.

El tipo auto_increment hará que su base de datos se ocupe de la próxima identificación de su tabla, es decir. se determinará automáticamente por el servidor de la base de datos cuando se ejecuta la inserción, que seguramente es seguro para la concurrencia.

Actualización:

¿Hay algo que te mantiene lejos de usar GenerationType.AUTO?

GenerationType.AUTO selecciona una forma apropiada de recuperar la identificación para su entidad. Entonces, en el mejor de los casos, utiliza la funcionalidad incorporada. Sin embargo, debe verificar los SQL generados y ver qué sucede exactamente allí, ya que MSSQL no ofrece secuencias, supongo que usaría GenerationType.IDENTITY.

Como dije, la columna auto_increment se ocupa de asignar el siguiente valor de id, es decir. no hay ningún problema de concurrencia allí, incluso con múltiples hilos abordando la base de datos en paralelo. El desafío es transferir esta característica para ser utilizada por JPA.

+0

Cuando dijo: 'El desafío es transferir esta característica para ser utilizada por JPA'., ¿Se refiere al uso de' @ GeneratedValue'? Así que intento establecer la columna en la tabla 'AUTO_INCREMENT', luego intento crear múltiplos' Persona'. La primera persona crea correctamente con el inicio de 'id' para que sea 5, pero genera una excepción para la persona 2. 'Clave primaria nula o cero encontrada en la unidad de clon de trabajo '. ¿No podemos simplemente anotar la identificación con '@ Id', sin' @ GeneratedValue', luego persistir el objeto de la entidad y dejar que la base de datos con 'PK AUTO_INCREMENT' se encargue de ello? –

+0

¿Puedes mostrar tu mapeo? Debería usar '@ GeneratedValue' para indicar a la implementación de JPA que se trata la ID. Aquí hay un enlace para ayudarle a ponerse en marcha: http://www.developerscrappad.com/408/java/java-ee/ejb3-jpa-3-ways-of-generating-primary-key-through-generatedvalue/ –

11

A: utiliza la generación de ID IDENTIDAD, @GeneratedValue (identidad)

B: se utiliza la tabla de generación de ID

JPA soporta tres tipos, la identidad, la secuencia y la mesa.

Hay intercambios con ambos.

La IDENTIDAD no permite la asignación previa, por lo que requiere un SELECCIONAMIENTO adicional después de cada INSERTAR, evita la escritura de lotes y requiere una descarga para acceder a la identificación que puede conducir a una concurrencia deficiente.

TABLE permite la preasignación, pero puede tener problemas de concurrencia con bloqueos en la tabla de secuencias.

Técnicamente la generación de id de SEQUENCE es la mejor, pero no todas las bases de datos lo admiten.

Con la secuencia TABLE si usa un tamaño de preallocaiton de 100, entonces solo cada 100 inserciones bloquearán la fila en la tabla de secuencia, por lo tanto, siempre que no tenga 100 insertos al mismo tiempo, no lo hará sufrir cualquier pérdida en concurrencia. Si su aplicación hace muchas inserciones, tal vez use un valor de 1000 o mayor.

EclipseLink usará una transacción separada para la secuencia TABLE, por lo que se reducirá cualquier problema de concurrencia con bloqueos en la tabla de secuencias. Si está utilizando JTA, necesita especificar un origen de datos no jta para hacer esto y configurar un conjunto de conexión de secuencia en sus propiedades persistence.xml.

+0

Su información sobre 'TABLE sequencing a preallocaiton size' me ayuda mucho cuando decido usar la secuencia' TABLE' para mi implementación. Deberías tener esta recompensa, esperaré un poco más para ver si alguien tiene otra idea para contribuir, si no, te concederé la recompensa. muchas gracias –

Cuestiones relacionadas