database - que - tier software architecture
Lógica: base de datos o aplicación/2(control de restricciones) (7)
Debe detectar la excepción de la base de datos a menos que pueda garantizar que su aplicación sea la única que inserte filas (y alguna vez insertará filas) en su base de datos.
EDITAR: Puede que haya malinterpretado la pregunta, pero aún diría que la opción B (HibernateSessionFactory arroja la excepción ConstraintException de la base de datos) es la mejor opción. Siempre hay una pequeña posibilidad de que otra aplicación pueda insertar algo en el intervalo de tiempo entre su cheque y la llamada a la función real. Además, la única manera de verificar si un embaucador es realizar una consulta adicional es simplemente una pérdida de rendimiento innecesaria.
Mi comprensión original de la pregunta era que en la opción A, la verificación de engaño se realizaría internamente (es decir, utilizando únicamente las estructuras de datos que el programa ya había creado, y sin consulta hasta el INSERT). Mi respuesta original fue en respuesta a este método.
Esta es una versión específica de esta pregunta .
Quiero verificar si estoy insertando una fila duplicada. ¿Debo verificarlo programáticamente en mi capa de aplicación?
if (exists(obj))
{
throw new DuplicateObjectException();
}
HibernateSessionFactory.getSession().save(obj);
¿o debería atrapar la excepción lanzada por la capa de la base de datos y activar cuando violo el contraint?
try
{
HibernateSessionFactory.getSession().save(obj);
}
catch(ConstraintViolationException e)
{
throw new DuplicateObjectException();
}
EDITAR: En otras palabras: aunque la restricción está ahí para permanecer (es un buen diseño de la base de datos de todos modos, y no puedo estar seguro de que mi aplicación será la única que accede a la tabla) debo confiar en la restricción y manejar la excepción su violación se levantará, o será mejor que compruebe de todos modos?
EDIT2: Por supuesto que compruebo + inserto dentro de una transacción, bloqueando la tabla para asegurar que ningún otro proceso está escribiendo otro registro mientras tanto
En general, trato de evitar la codificación que se basa en errores que se lanzan porque hice algo mal. A veces, sin embargo, eso es todo lo que puedes hacer. En su situación, creo que debería verificar primero.
En primer lugar, debe tener una clave principal o una restricción única en la base de datos para hacer cumplir esta singularidad de manera adecuada, sin dudas.
Dado que la restricción existe, ¿de qué manera debe codificar en la aplicación? Mi preferencia sería probar el inserto y atrapar las excepciones. Debido a que presumiblemente la mayoría de las inserciones tendrán éxito, solo unas pocas fallarán como duplicadas (¡eso es lo que implica "excepción"!): Es ineficiente realizar una comprobación existente antes de cada inserción, cuando la base de datos va a realizar su propia comprobación de restricciones de todos modos.
Además, teóricamente es posible que la comprobación existente sea incorrecta de todos modos, si alguien más logra establecer un registro con el mismo valor clave en el pequeño intervalo entre tu cheque existente y tu inserción. Entonces, si no atrapa la excepción de la base de datos, creerá que el inserto tuvo éxito cuando en realidad no lo hizo.
Esto se romperá (permitiendo entradas duplicadas) si la restricción se descarta por algún motivo (por lo general, trabajo de mantenimiento en el que el DBA no vuelve a habilitarlo). Debe verificar esta situación dentro de la aplicación.
Sin embargo, es un buen diseño de la base de datos hacer que la base de datos haga cumplir la restricción (como usted ha señalado correctamente) ya que otros también pueden estar usando la base de datos. Como generalización, es mejor suponer que las aplicaciones y las bases de datos viven en una relación M: M; este será el caso casi todo el tiempo.
Las excepciones lanzadas por Hibernate (o cualquier componente de ORM) tienden a ser difíciles de interpretar.
Si la excepción tiene suficiente información como para que pueda generar un mensaje de error que realmente ayude al usuario, simplemente tome la excepción, analícela y siga.
Si la excepción no tiene suficiente información, debe verificar la condición de error y generar un mensaje de error útil para el usuario que indica que está haciendo algo incorrecto.
La pregunta es: ¿cuán opaca es la excepción? Algunos son bastante opacos. Otros tienen suficiente para analizar la cadena del mensaje y descubrir qué decir al usuario.
Una vez que hibernate arroja una excepción de la sesión, debe descartar la sesión (consulte la sección 11.2.3). Por lo tanto, si necesita verificar dups y continuar usando la misma sesión, no tiene más remedio que verificar primero en la aplicación.
También hay una posibilidad con el código en el primer fragmento de que otro proceso podría insertar un registro que provocaría la excepción duplicada entre el momento en que comprueba el registro duplicado y el momento en que realmente se inserta.
Verifica que el objeto exista únicamente en el código de la aplicación y, una vez que esté satisfecho de que no existe, guarde el objeto alegremente. Pero otro cliente simultáneo podría insertar su propio objeto en el momento entre sus dos líneas de código. Por lo tanto, obtendría una excepción de Duplicado de todos modos, solo que esta vez no la captaría.
Debes hacer save () y atrapar la excepción. De lo contrario, tiene una condición de carrera con otros clientes simultáneos que trabajan en la misma base de datos.