2010-12-20 10 views
5

Digamos que tengo una aplicación de escritorio que actúa como un garaje para un montón de coches:Múltiples Hilos para acceder a la base de datos: uno con una larga operación, uno con transacciones cortas

@Entity 
public class Garage { 
    private List<Car> cars = new ArrayList<Car>(); 
    ... 
} 

La aplicación de escritorio tiene una "simulación "botón que inicia un nuevo hilo y comienza a llamar a los métodos en el garaje, coche, rueda, etc. Esta simulación puede tardar hasta 10 minutos en ejecutarse. Por el momento tengo una clase que tiene este aspecto:

beginTransaction(); 
Garage garage = garageDao.findGarage(1); 
List<Car> cars = garage.getCars(); 
for (Car car : cars) { 
    // call methods on the car to lazily fetch other things like wheels... 
} 
commitTransaction(); 

Este código sólo lo hace "lee" y nunca "escribe"

Así que lo anterior puede llevar mucho tiempo, dependiendo de lo mal que los coches necesitan un servicio. Mientras sucede lo anterior, el usuario puede continuar trabajando con la aplicación de escritorio. Pueden elegir cambiar el color de un automóvil que se está utilizando en la transacción anterior.

Mi pregunta es si la transacción larga anterior va a evitar el cambio del color del automóvil? es decir, ¿el usuario que cambia el color del automóvil en la aplicación de escritorio no podrá confirmar el cambio hasta que finalice la transacción larga?

+0

¿Por qué necesita una transacción para leer? ¿Estás usando la recuperación perezosa? – saugata

+0

¿Debe el 'hilo de actualización' ser una sola unidad transaccional? ¿O no hay actualizaciones? Usted dice "Este código solo 'lee' y nunca 'escribe'. Entonces - al igual que saugata preguntó - ¿por qué necesita transacciones? –

+0

sí, los métodos que se llaman en un automóvil podrían ser algo así como getWheels() y están siendo perezosamente obtenido – digiarnie

Respuesta

4

¿Por qué debería? De manera predeterminada, usa transacciones optimistas, por lo que no se aplica ningún bloqueo a las filas que se leen (a menos que no nos muestre algunas llamadas de bloqueo JPA2). El compromiso de la transacción debería entonces verificar la versión optimista de los registros (si tiene una versión definida) y usar eso para decidir si comprometer los cambios.

+0

no, no hay llamadas de bloqueo() – digiarnie

0

La respuesta dependerá de la base de datos que utilice y más importante, qué nivel de aislamiento de transacción.

Pero la respuesta es, en general, no: No deberían bloquear (Pero como dije, depende de la base de datos y el nivel de transacción).

0

Como arriba:

Normalmente, operaciones de sólo lectura no debe bloquear las operaciones de escritura en una base de datos. Por lo tanto, su hilo de lectura largo no debe bloquear las operaciones de escritura cortas.

Supongo que es posible configurar un nivel de aislamiento para su base de datos y conexión que las escrituras pueden ser bloqueadas por largas instrucciones de lectura pero esto NO es el predeterminado en ninguno de los tipos de bases de datos que conozco.

Cuestiones relacionadas