uncommitted transaction transacciones sucia read niveles manejo lectura committed aislamiento java database hibernate jpa transactions

java - transaction - Nivel de aislamiento de transacciones



set transaction isolation level snapshot in sql server (2)

Trataré de describir mi problema en los niveles de aislamiento de transacción JPA.

Estructura de la base de datos

  • Table1 -> con PK definida como fecha (''ddMMyyyy'')
  • Table2 -> con FK a Table1

JPA (nivel de aislamiento :: read_commited ) - código:

Query query = em.createQuery("from Table1 trd where trd.id = :d"); query.setParameter("d", date); Table1 t = null; try{ t = (Table1) query.getSingleResult(); }catch(javax.persistence.NoResultException e){ t = null; } if(t==null){ t=new Table1 (date); em.persist(trd); } for(Table2 q:tables2){ q.setTable1(t); em.merge(q); }

Así que verifique el procedimiento si el registro existe en db y, si no, cree uno nuevo. El método es completamente corect si el sistema está basado en un solo hilo. De lo contrario, hay una situación posible como esta:

  • Tema 1: verificar si la entidad representa por fecha existe en la base de datos
  • Tema 2: Haz exactamente lo mismo

Ambos piensan que ese registro aún no existe, así que agrega uno nuevo. Todo está bien hasta el momento de realizar transacciones. El primero se realizará sin excepción, compre la segunda excepción de aumento relacionada con la duplicación de clave principal.

¿Hay alguna posibilidad de preservar tal situación excepto cambiar el nivel de aislamiento a SERIALIZABLE ?


Sí, en el nivel de aislamiento general = SERIALIZABLE debería resolver su problema. No subestime los efectos secundarios al cambiar el nivel de aislamiento a la opción más rígida. Puede influir en la utilización de la base de datos y en el rendimiento de las solicitudes. Tal vez puedas comprometer explícitamente tu TRX después de crear T1, luego abrir otro TRX: EntityManager.getTransaction (). Commit ()

Aún debe atrapar la excepción de clave duplicada.


Este es uno de los problemas más difíciles de resolver con bases de datos en un entorno altamente concurrente. Al final, su única solución real es atrapar la excepción y tratarla adecuadamente.

Es difícil saber qué podría ser, según el código que proporcionó. Si se trata de una aplicación web, lo más probable es que desee capturar la excepción de clave duplicada y mostrar algún mensaje útil al usuario final. Tales como "Este registro ya fue creado", o algo parecido.