2012-08-10 21 views
5

Estoy usando PL/SQL (Oracle 11g) para actualizar la columna del salario de la tabla EMPLOYEES.uso de la instrucción FOR UPDATE

He usado dos scripts para hacer lo mismo, es decir, actualizar el salario de los empleados.

Una secuencia de comandos usa la instrucción FOR UPDATE OF mientras que otra secuencia de comandos no la usa. En ambos casos, descubrí que Oracle mantiene los bloqueos de nivel de fila hasta que ejecutamos los comandos ROLLBACK o COMMIT.

Entonces, ¿cuál es la diferencia entre dos scripts?

¿Cuál es mejor usar?

Éstos son los dos guiones que estoy hablando:

-- Script 1: Uses FOR UPDATE OF 

declare 
cursor cur_emp 
is 
select employee_id,department_id from employees where department_id = 90 for update of salary; 
begin 
    for rec in cur_emp 
    loop 
    update Employees 
    set salary = salary*10 
    where current of cur_emp; 
    end loop; 
end; 


--Script 2: Does the same thing like script 1 but FOR UPDATE OF is not used here 

declare 
cursor cur_emp 
is 
select employee_id,department_id from employees where department_id = 90; 
begin 
    for rec in cur_emp 
    loop 
    update Employees 
    set salary = salary*10 
    where Employee_ID = rec.employee_id; 
    end loop; 
end; 

me encontré con que Oracle adquirió los bloqueos a nivel de fila en ambos casos. Entonces, ¿cuál es el beneficio de usar FOR UPDATE OF y cuál es la mejor forma de codificación?

+2

No se olvide: si employee == mrp then set salarial + = 100000 – stark

Respuesta

12

Cuando especifica FOR UPDATE, la fila se bloquea en el punto en que SELECT los datos. Sin FOR UPDATE, la fila está bloqueada en el punto UPDATE de la fila. En el segundo script, otra sesión podría bloquear la fila entre el momento en que se ejecutó el SELECT y el punto que intentó UPDATE.

Si se trata de una instrucción SELECT que devuelve relativamente pocas filas y un bucle interno cerrado, es poco probable que haya una diferencia apreciable entre las dos. Agregar un FOR UPDATE en el SELECT también le da la oportunidad de agregar una cláusula de tiempo de espera si no desea que su secuencia de comandos se bloquee indefinidamente si alguna otra sesión tiene una de las filas que está tratando de actualizar bloqueada.

+0

¿No se ejecutará más rápido el script 'FOR UPDATE' ya que está accediendo efectivamente a la actualización mediante' ROWID' en la cláusula 'WHERE CURRENT OF'? – Ollie

+2

@Ollie - Posible. Pero el 'SELECT' tiene que visitar cada fila para establecer el atributo de bloqueo antes de devolver la primera fila, por lo que implicará golpear cada fila por segunda vez (aunque es probable que el segundo golpe esté en un objeto en caché). Esperaría que los dos se compensen entre sí. Además, si el objetivo es maximizar la velocidad, escribiría una sola instrucción 'UPDATE' o al menos operaciones masivas PL/SQL, en lugar de un cursor' FOR' de cursor de fila por fila. –

Cuestiones relacionadas