2011-10-05 16 views
6

Estoy experimentando con el bloqueo optimista.Bloqueo optimista y org.hibernate.StaleObjectStateException:

que tienen la clase siguiente:

@Entity 
public class Student { 

    private Integer id; 
    private String firstName; 
    private String lastName; 
    private Integer version; 
@Version 
    public Integer getVersion() { 
     return version; 
    } 

//all other getters ommited. 
} 

ahora estoy ir a buscar uno de los estudiantes y tratar de actualizar sus propiedades al mismo tiempo.

Thread t1 = new Thread(new MyRunnable(id)); 
    Thread t2 = new Thread(new MyRunnable(id)); 
    t1.start(); 
    t2.start(); 

y en el interior de MyRunnable:

lo que está sucediendo que las actualizaciones primera transacción objeto con éxito y segunda transacción Lanza:

org.hibernate.StaleObjectStateException: Row was updated or deleted by another transaction (or unsaved-value mapping was incorrect): [com.vanilla.entity.Student#1] 

Esto está bien.

Mi pregunta es: 1) ¿Qué debo hacer si quiero que la segunda transacción no haga nada y no lanzar ninguna excepción.

2) ¿Qué debo hacer si deseo que la segunda transacción anule los datos actualizados en la primera transacción?

Gracias.

Respuesta

7

me da un intento de responder a sus preguntas:

  1. Se utiliza el bloqueo optimista. Así que quiere que se genere un OptimisticLockException en conflicto de versiones, pero puede atraparlo y no hacer nada. No puede desactivarlo por un segundo (lo que sea que eso signifique) transacción porque no sabe si se producirá un conflicto de versión (esta es la esencia de la estrategia de bloqueo optimista: la hipótesis optimista supone que se ganó un conflicto de versión 't ocurrir muy a menudo)

  2. Si se produce un OptimisticLockException, que básicamente tienen 2 opciones:

    1. descartar los cambios (y tal vez refrescar el estado actual)
    2. actualización sólo la versión de su entidad (entidades) e intentar comprometer nuevamente

    El problema es cómo o quién va a decidir qué estado es el verdadero "correcto" (es decir, el último) si tiene actualizaciones concurrentes. Mientras se garantice la consistencia, no me importaría.

0

Descargo de responsabilidad: esta es una sugerencia; No lo he probado yo mismo.

Daría hasta el campo de versión del todo, y regular la estrategia de bloqueo optimista entidad a "ninguno" en el mapeo XML:

<class name="Student" optimistic-lock="none"/> 

o como una anotación:

@Entity(optimisticLock=OptimisticLockType.NONE) 

Son Específico de Hibernate, no los encontrará en la especificación JPA.

0

Tuve la misma excepción. Se resolvió una vez que cambió

@GeneratedValue(strategy = GenerationType.SEQUENCE) 

a

@GeneratedValue(strategy = GenerationType.AUTO) 

en mi entidad.

Mi aplicación se ejecuta en el servidor MySQL.

Cuestiones relacionadas