2010-09-08 7 views
7

Estoy escribiendo una aplicación que sincroniza las entidades de un origen de datos de terceros en nuestro propio esquema, con un paso de transformación/mapeo en el medio. Estoy usando Hibernate para representar y persistir las entidades en nuestro propio esquema. Un problema con el que me estoy encontrando es que tengo una clave única de varias columnas en una de mis tablas. El comportamiento que me gustaría ver es análogo a un upsert: cuando Hibernate va a persistir en una entidad y detecta una violación de restricción única, en su lugar realiza una actualización. Estamos utilizando MySQL, que proporciona una sintaxis de INSERTAR ... EN DUPLICADO DE ACTUALIZACIÓN DE LLAVE, pero no estoy seguro de cómo o si se puede hacer que Hibernate la use.¿Cómo imitar el comportamiento de inserción utilizando Hibernate?

Supongo que siempre puedo probar el inserto, y si encuentro una excepción, hago una actualización, pero eso me parece raro y no es óptimo. ¿Algún consejo sobre una forma limpia de hacer esto?

Respuesta

4

Estamos utilizando MySQL, que proporciona una sintaxis de INSERTAR ... EN DUPLICADO CLAVE ACTUALIZACIÓN, pero no estoy seguro de cómo o si se puede hacer Hibernate para hacer uso de ella?

Parece que alguien did it reemplazando el comunicado sql-insert utilizado por Hibernate para esta entidad. Si no te importa no ser portátil (y probablemente utilices un procedimiento almacenado), échale un vistazo.

Supongo que siempre puedo probar el inserto, y si encuentro una excepción, hago una actualización, pero eso me parece raro y no es óptimo. ¿Algún consejo sobre una forma limpia de hacer esto?

Otra opción sería:

  1. realizar una selección de la clave única
  2. si encuentra un registro, que se actualizará
  3. si no encuentra un registro, lo crea

Pero a menos que se bloquea todo el mesa (s) durante el proceso, se puede hacer frente a alguna condición de carrera en una el entorno multiproceso y distribuido y el paso 3 pueden fallar. Imaginemos dos procesos simultáneos:

Rosca 1:

  • comienzan trans
  • realiza una selección en una tecla
  • Ningún dato encontrado
  • crear un registro
  • cometer

Hilo 2:

  • comienzan trans
  • realiza una selección en la misma tecla
  • Ningún dato encontrado
  • crear un registro
  • commit (fallar! porque el hilo 1 fue más rápido y un registro con la misma clave única que existe ahora)

Así que habría que aplicar algún tipo de mecanismo de reintento de todos modos (bloqueo de toda la tabla (s) no es una buena opción OMI) .

3

La condición de carrera se pueden evitar "seleccione ... para la actualización"

+3

Si los partidos selectos ninguna fila, no hay filas serán bloqueadas por "actualización". La condición de carrera no se evita. –

Cuestiones relacionadas