Transacciones y concurrencia
Sistemas de persistencia de objetos
� Es la demarcación de una unidad de trabajo
� JPA permite trabajar con varios API de
Transacción ACID
� JPA permite trabajar con varios API de transacciones
� JSE JDBC
� JTA
� Declarativas (EJB)
nov-08 Alberto M.F.A. [email protected] 2
Control de transacciones
nov-08 Alberto M.F.A. [email protected] 3
Excepciones JPA�Todas las excepciones JPA son fatales y dejan el contexto de persistencia inutilizado
�Todas las excepciones lanzadas por EntityManager provocan rollback()
nov-08 Alberto M.F.A. [email protected] 4
EntityManager provocan rollback()
�Todas las de Query tb, excepto NoResultException yNonUniqueResultException.
Todas NO chequeadas
Control de concurrencia
� Las trx ACID crean la ilusión de que cada usuario es único en la base de datos � aíslan a unos de otros
� El aislamiento tradicionalmente se consigue con bloqueos a nivel de fila, de rangos o de tabla:
De lectura (compartido)
nov-08 Alberto M.F.A. [email protected] 5
� De lectura (compartido)� todos podemos leer pero nadie escribir
� De escritura (exclusivo)� nadie puede leer porque voy a escribir y nadie más puede
escribir
� Oracle y PostgreSQL usan MVCC
Problemas debidos a concurrencia
� Actualización perdida (lost update)
� Lectura sucia (dirty read)
� Lectura no repetible (non repetible read)
nov-08 Alberto M.F.A. [email protected] 6
� Lectura no repetible (non repetible read)
� Doble actualización (second lost update)
� Lectura fantasma (phantom read)
Problemas debidos a concurrencia (2)
nov-08 Alberto M.F.A. [email protected] 7
Lost update: Dos trx sin bloqueo actualizan los mismos datos. La trxB hace rollback y se pierden los datos de trxA
Dirty read: TrxA lee datos que luego desaparecen por rollback
Problemas debidos a concurrencia (3)
nov-08 Alberto M.F.A. [email protected] 8
Unrepeatable read:Durante txA txB es más rápida y modifica datos que vuelve a necesitar txA
Phantom read: Durante txA txB inserta (o modifica) nuevos datos que txA va a detectar más tarde repitiendo la consulta (u otra que depende de ellos)
Second lost update: Caso especial de unrepeatable read. La actualización de txB es sobreecrita por la de txA.
Niveles de aislamiento ANSI
� Read uncommitted� Tiene todos los problemas, solo protege frente a
sobreescrituras (lost update) � B.L. en UPDATE
� Read commited
nov-08 Alberto M.F.A. [email protected] 9
� Read commited� Protege de dirty read � B.E. en UPDATE
� Repetible read� Protege de dirty y non repetible read � B.L. en
SELECT, B.E. en UPDATE
� Serializable� Protege de phantom, dirty y non repetible read� B.L. SELECT en tablas o rangos� B.E. UPDATE en tablas o rangos
Ajuste del nivel de aislamiento
� Se si pone mal problemas:
� Solo se van a notar cuando el sistema está en carga
nov-08 Alberto M.F.A. [email protected] 10
en carga� Cuando ya estamos en producción
� Si se pone nivel muy restricitivo se ralentiza mucho el acceso
� Si se pone muy bajo aparecerán datos inconsistentes difíciles de depurar
¿Cuál escoger?
� Depende de necesidades, pero:� Read uncommitted nunca (solo expertos)
� Serializable no es frecuente� ¿Realmente me van a afectar los phantom reads? �
nov-08 Alberto M.F.A. [email protected] 11
� ¿Realmente me van a afectar los phantom reads? �pocas trx son así
� La duda mayor está entre read committed y repeatable read
� Read commited no protege del second lost update y sí puede ser importante
� Repetible read sí protege frente a second lost update� Pero no lo tienen todas las BDD (oracle no lo tiene,
PostgreSQL tampoco, …)
Read commited puede servir…
� Casi todas las BDD tienen read committedpor defecto
� Con bloqueos pesimistas se consigue repetible read
nov-08 Alberto M.F.A. [email protected] 12
repetible read� Con control optimista se puede evitar el
second lost update� Con tener la BDD en read commited por
defecto sirve para el 90% si se añaden estos controles a la aplicación
Ajuste del nivel en Hibernate
� Hibernate nativo usa por defecto el nivel de la conexión JDBC
nov-08 Alberto M.F.A. [email protected] 13
Hibernate nativo usa por defecto el nivel de la conexión JDBC� JDBC a su vez usa el nivel por defecto en la BDD� Depende de la BDD, hay que consultar la
documentación � suele ser read commited o repetible read
� Con el ajuste se cambia para ¡todas las transacciones !
� Ajuste en persistence.xml
Control pesimista y optimista
ROLLBACK
nov-08 Alberto M.F.A. [email protected] 14
Lock Lock
ROLLBACK
Lock v1.0 v2.0 v1.0
En BDD ya no es v1.0
PESIMISTA OPTIMISTA
Control optimista
� Diferencia entre trx de sistema y trx de aplicación
� El control optimista además permite
nov-08 Alberto M.F.A. [email protected] 15
� El control optimista además permite detectar cambios en actualizaciones entre trx de sistema
La solución optimista es añadir versiónersión a los objetos
Versionado de objetos con campo versión
� Añadir información al objeto para poder detectar cambios entre el estado detached y persistent
nov-08 Alberto M.F.A. [email protected] 16
detached y persistent
� Campo versión (un entero)
� Timestamp (de la última modificación)
Mapeado de campos
Sin get/set
Tipos válidos para versionado
!
nov-08 Alberto M.F.A. [email protected] 17
Sin get/set
JPA gestiona los campos versión de forma automática
¿Qué provoca cambio de versión?
� No estándar JPA
� Hibernate:� Cualquier cambio en un campo de la entidad� Cualquier cambio en un campo de la entidad
� Cambios en campos de Value Types
� Cambios en associaciones @…ToMany(colecciones de entidades)
� Añadir o quitar elementos a la colección
� No provoca cambios modificar entidades asociadas
nov-08 Alberto M.F.A. [email protected] 18
Versionado sin campo versión
� Solo válido para objetos que se hayan cargado en la misma sesión
nov-08 Alberto M.F.A. [email protected] 19
NO es JPA estándar
Control pesimista
� En circunstancias normales el contexto de persistencia da protección repetible read al haber una única copia en memoria (aunque la BDD no esté en ese nivel)
� Pero en algunas ocasiones esta protección no se consigue
En este entretiempo otra
nov-08 Alberto M.F.A. [email protected] 20
En este entretiempo otra trx puede haber cambiado la descripción
Se proyectan escalares, no objetos: no hay chaché de contexto
� El control pesimista sube el nivel a repetible read sin cambiar BDD
Control pesimista
Se impone un bloqueo en la fila
nov-08 Alberto M.F.A. [email protected] 21
Impone un bloqueo de fila
Modos de bloqueo
� LockModeType.READ
� Impone bloqueo de lectura
� SELECT * FROM … FOR UPDATE de Oracle (o equivalente)
� LockModeType.WRITE� LockModeType.WRITE
� Lo mismo que el anterior pero fuerza el incremento de versión
nov-08 Alberto M.F.A. [email protected] 22
Fuerza cambio de versión que no se produciría