Foros del Web » Programando para Internet » PHP » Frameworks y PHP orientado a objetos »

Control elegante de transacciones

Estas en el tema de Control elegante de transacciones en el foro de Frameworks y PHP orientado a objetos en Foros del Web. Hola foristas: Estoy trabajando con PHP-Oracle y estoy llevando las transacciones desde el propio php y no desde los procedimientos almacenados Oracle ya que en ...
  #1 (permalink)  
Antiguo 27/07/2008, 20:08
 
Fecha de Ingreso: enero-2007
Mensajes: 272
Antigüedad: 17 años, 4 meses
Puntos: 5
Pregunta Control elegante de transacciones

Hola foristas:

Estoy trabajando con PHP-Oracle y estoy llevando las transacciones desde el propio php y no desde los procedimientos almacenados Oracle ya que en ocasiones ejecuto 4 SP y de acuerdo a esto debo hacer commit o rollback.

Todo lo anterior es, para mantener la integridad de los datos y no dejar (registros sin integridad).

Actualmente lo estoy haciendo como se ve en el siguiente código.

Código PHP:
if (isset($_POST['btnGrabar'])) {

    
$mensaje validar();
    if (
$error == false) {
        
$ordenCompra = array('id_cliente' => $idCliente,
                             
'nroOrdCompra' => $nroOrdCompra'nroPedido' => $nroPedido,
                                    
'descripcion' => $descripcion'fecha' => $fecha,
                                    
'proveedor' => 1'neto' => $neto'iva' => $iva,
                                    
'total' => $total'estado' => 'PEN');

        
$mensaje registrarOrdCompra($ordenCompra);

        foreach(
$_SESSION['grilla'] as $codBarra => $valor){
            if (
$mensaje == '')
                
$mensaje registrarOrdCompraDet($idCliente$nroOrdCompra$valor['coditem'],
                    
$valor['pCosto'] , $valor['cant']);
            if (
$mensaje == '')
                
$mensaje registrarOrdCompraArt($idCliente$nroOrdCompra$valor['codartic'],
                    
$valor['pCosto'], $valor['cant']);
            if (
$mensaje == '')
                
$mensaje registrarOrdCompraItem($idCliente$nroOrdCompra$valor['coditem'],
                    
$valor['cant']);
        }

        if (
$mensaje == '')
            
oci_commit($conn);
        else{
            
oci_rollback($conn);
            
$tpMensaje "error";
        }
    }

Como podrán darse cuenta, lo que hago es rastrear el error y de acuerdo a este seguimiento aplico commit o en su defecto rollback.

Mi idea es hacer esto mucho más elegante, me gustaria hacer que existiera una especie de excepción y de acuerdo a esto aplicar rollback, pero todavía no lo veo muy claro, quizás hasta componer un clase, quien sabe

¿Alguien tiene una idea de hacer algo mas eficiente y elegante?

Gracias...

Última edición por lucasarts_18; 05/08/2008 a las 21:28
  #2 (permalink)  
Antiguo 27/07/2008, 20:59
Avatar de GatorV
$this->role('moderador');
 
Fecha de Ingreso: mayo-2006
Ubicación: /home/ams/
Mensajes: 38.567
Antigüedad: 18 años
Puntos: 2135
Respuesta: Control elegante de transacciones

Lo mas facil es que uses PDO, y con eso puedes hacerlo como lo planteas, en caso de un error haces el rollback.

Saludos.
  #3 (permalink)  
Antiguo 28/07/2008, 07:08
 
Fecha de Ingreso: enero-2007
Mensajes: 272
Antigüedad: 17 años, 4 meses
Puntos: 5
Respuesta: Control elegante de transacciones

Cita:
Iniciado por GatorV Ver Mensaje
Lo mas facil es que uses PDO, y con eso puedes hacerlo como lo planteas, en caso de un error haces el rollback.

Saludos.
según la ayuda de PDO.

Código PHP:
<?php
try {
  
$dbh = new PDO('odbc:SAMPLE''db2inst1''ibmdb2'
      array(
PDO::ATTR_PERSISTENT => true));
  echo 
"Connected\n";
  
$dbh->setAttribute(PDO::ATTR_ERRMODEPDO::ERRMODE_EXCEPTION);

  
$dbh->beginTransaction();
  
$dbh->exec("insert into staff (id, first, last) values (23, 'Joe', 'Bloggs')");
  
$dbh->exec("insert into salarychange (id, amount, changedate) 
      values (23, 50000, NOW())"
);
  
$dbh->commit();
  
} catch (
Exception $e) {
  
$dbh->rollBack();
  echo 
"Failed: " $e->getMessage();
}
?>
Este es el comportamiento deseado, pero migrar la aplicación que ya lleva un 60% sería un suicidio, pero lo tendré en cuenta para futuros desarrollos.
Además que creo que PDO será un estandar (en alguna parte lo leí )

Mientras tantos intentaré emitar el compartimiento, quizás haciendo que las funciones que gatillan los procedimientos almacenados en vez de devolver un mensaje de error hagan levantar una excepción y luego capturarlas desde afuera.

Haré el intento....

Si alguien tiene un ejemplo, mejor todavía.

Gracias GatorV-

Saludos.-
  #4 (permalink)  
Antiguo 28/07/2008, 07:49
Avatar de GatorV
$this->role('moderador');
 
Fecha de Ingreso: mayo-2006
Ubicación: /home/ams/
Mensajes: 38.567
Antigüedad: 18 años
Puntos: 2135
Respuesta: Control elegante de transacciones

Pues puedes hacerlo por ejemplo:
Código PHP:
function doQuery($query) {
      if(
algo_mal()) {
              throw new 
Exception"algo ocurrio mal" );
      }
}

try {
    
doQuery($sql);
} catch( 
Exception $e ) {
    
//rollback

Saludos.
  #5 (permalink)  
Antiguo 28/07/2008, 12:24
Avatar de enriqueplace  
Fecha de Ingreso: mayo-2005
Ubicación: Uruguay / Argentina
Mensajes: 1.102
Antigüedad: 19 años
Puntos: 32
Respuesta: Control elegante de transacciones

Cita:
Este es el comportamiento deseado, pero migrar la aplicación que ya lleva un 60% sería un suicidio, pero lo tendré en cuenta para futuros desarrollos.

Comentario al margen (y aprovechando la oportunidad):
cuando suceden este tipo de cosas muchas veces es por un mal o insuficiente diseño. Hay una frase que una personalidad de la informática dijo una vez (interpretación libre):

"Cualquier problema en computación puede resolverse añadiendo otra capa de abstracción" - David Wheeler


Si dependes de una entidad de más alto nivel, las implementaciones de bajo nivel quedan ocultas, por lo tanto, los cambios no deberían afectar a todo tu sistema.

Caso hipotético: si todo tu desarrollo en PHP usa sentencias mysql_[algo], y a mitad del desarrollo deciden cambiar a PostreSQL, muy probablemente debas modificar todo tu código, pero, si tienes una clase "que te abstrae la persistencia", solo cambiarás internamente pero no afectará a todo tu sistema.

Nota: es un ejemplo, obviamente no conozco todos los detalles de tu problema y no por eso quiero generalizar y ser injusto

PD: También te puede iluminar temas com los TADs (Tipos Abstractos de Datos).
__________________
Blog phpsenior.com Cursos a Distancia surforce.com
  #6 (permalink)  
Antiguo 28/07/2008, 12:49
venkman
Invitado
 
Mensajes: n/a
Puntos:
Respuesta: Control elegante de transacciones

Hombre, Enrique, está bien traducir libremente, pero lo que no está tan bien es dejarse fuera la mitad de la cita, sobre todo si eso cambia bastante el sentido de la misma. (en mi muy modesta opinión y sin ánimo de molestar)
  #7 (permalink)  
Antiguo 28/07/2008, 12:58
Avatar de enriqueplace  
Fecha de Ingreso: mayo-2005
Ubicación: Uruguay / Argentina
Mensajes: 1.102
Antigüedad: 19 años
Puntos: 32
Respuesta: Control elegante de transacciones

Dice "interpretación libre"... yo recuerdo haber leído la frase como la cito (no recuerdo la fuente), pero buscando otras referencias encuentro esta versión en wikipedia.. y como todo, hay que tomarlo con pinzas (ya que puede estar errado), por eso hago las aclaraciones del caso y dejo un link para contrastar.

La verdad que no me molestaría la acotación si hicieras un poco más de comprensión lectora y razonamiento deductivo
__________________
Blog phpsenior.com Cursos a Distancia surforce.com
  #8 (permalink)  
Antiguo 28/07/2008, 13:09
venkman
Invitado
 
Mensajes: n/a
Puntos:
Respuesta: Control elegante de transacciones

"Cualquier problema en computación puede resolverse añadiendo otra capa de abstracción. Pero eso normalmente creará otro problema." - David Wheeler

En el mismo enlace que tú has puesto está, no he necesitado buscar más. Como ves, no se trata de interpretar libremente, sino que estás cambiando el sentido de la cita.

Si realmente te molestan las acotaciones sigue tus propios consejos y aplica un poco más de "comprensión lectora" :)
  #9 (permalink)  
Antiguo 28/07/2008, 13:12
Avatar de enriqueplace  
Fecha de Ingreso: mayo-2005
Ubicación: Uruguay / Argentina
Mensajes: 1.102
Antigüedad: 19 años
Puntos: 32
Respuesta: Control elegante de transacciones

Estimado, lee lo que dije en los puntos anteriores, no entendiste nada de lo que dije (pero nada).

"Comprensión lectora 0".
__________________
Blog phpsenior.com Cursos a Distancia surforce.com
  #10 (permalink)  
Antiguo 28/07/2008, 13:18
venkman
Invitado
 
Mensajes: n/a
Puntos:
Respuesta: Control elegante de transacciones

Lo que tú digas

Última edición por venkman; 28/07/2008 a las 13:27
  #11 (permalink)  
Antiguo 28/07/2008, 13:32
Avatar de Lord Kazuky  
Fecha de Ingreso: junio-2006
Ubicación: 7F.00.00.01
Mensajes: 123
Antigüedad: 17 años, 10 meses
Puntos: 5
Respuesta: Control elegante de transacciones

Saludos!

Bueno hasta este momento yo he venido utilizando dos métodos del objeto sobre el cual se efectua el proceso.

Un método de tipo público (para este caso podria llamarse 'grabarCompra' o 'grabar') que inicia la transacción, y hace el commit o rollback segun se termine o no satisfactoriamente el proceso de grabar la Compra

Un metodo de tipo privado (por ejemplo 'procesoGrabarCompra' o 'procesoGrabar') que es el que hace todas las validaciones necesarias, realiza todo el 'trabajo sucio' y devuelve un valor verdadero o falso segun se pueda terminar o no el proceso satisfactoriamente.

Para los mensajes de error, dado a que aun no he implementado manejo de excepciones (necesito más practica) , venia escribiendo el mensaje del error en un atributo más de la clase. Y en caso de que el proceso me devuelva falso, pues puedo imprimirlo en pantalla, para el usuario o en registrarlo en algun LOG.
__________________
Saludos.
"Cualquier tonto puede escribir código que un computador entiende. Los buenos programadores escriben código que los humanos pueden entender. ;)"
  #12 (permalink)  
Antiguo 28/07/2008, 18:17
 
Fecha de Ingreso: enero-2007
Mensajes: 272
Antigüedad: 17 años, 4 meses
Puntos: 5
Respuesta: Control elegante de transacciones

Cita:
Iniciado por enriqueplace Ver Mensaje

Comentario al margen (y aprovechando la oportunidad):
cuando suceden este

Si dependes de una entidad de más alto nivel, las implementaciones de bajo nivel quedan ocultas, por lo tanto, los cambios no deberían afectar a todo tu sistema.

Caso hipotético: si todo tu desarrollo en PHP usa sentencias mysql_[algo], y a mitad del desarrollo deciden cambiar a PostreSQL, muy probablemente debas modificar todo tu código, pero, si tienes una clase "que te abstrae la persistencia", solo cambiarás internamente pero no afectará a todo tu sistema.
Uso directamente las funciones OCI_Fetch, OCI_Execute, etc... ya que no encontré la forma de gatillar package de oracle que tuvieran como parámetros record definidos como objetos oracle.

Inicialmente había pensado en ADODB (ya he desarrollado cosas con esta librería), pero no hallé la forma de trabajar de la manera que cité anteriormente.

Y montar mi propia librería sobre las funciones OCI, me parecía un trabajo titánico para el poco tiempo que contaba.

Por cierto la solución encontrada la deje documentada en el foro para quien lo requiera a futuro.

Saludos .-

Última edición por lucasarts_18; 29/07/2008 a las 09:10
  #13 (permalink)  
Antiguo 28/07/2008, 18:23
Avatar de enriqueplace  
Fecha de Ingreso: mayo-2005
Ubicación: Uruguay / Argentina
Mensajes: 1.102
Antigüedad: 19 años
Puntos: 32
Respuesta: Control elegante de transacciones

Cita:
Iniciado por lucasarts_18 Ver Mensaje
Y montar mi propia librería sobre las funciones OCI, me parecía un trabajo titánico para el poco tiempo que contaba.
No tiene nada de titánico hacer una clase tipo "wrapper", del tipo BaseDeDatos.class.php, creas tu propios métodos que son "pasamano" de la misma funcionalidad y luego, ante cambios, los implementas internamente y el resto de tu sistema no se entera.

Cruza los dedos que no te pidan cambios durante o cuando tengas terminado el sistema.
__________________
Blog phpsenior.com Cursos a Distancia surforce.com
  #14 (permalink)  
Antiguo 28/07/2008, 20:17
 
Fecha de Ingreso: enero-2007
Mensajes: 272
Antigüedad: 17 años, 4 meses
Puntos: 5
Respuesta: Control elegante de transacciones

Cita:
Iniciado por GatorV Ver Mensaje
Pues puedes hacerlo por ejemplo:
Código PHP:
function doQuery($query) {
      if(
algo_mal()) {
              throw new 
Exception"algo ocurrio mal" );
      }
}

try {
    
doQuery($sql);
} catch( 
Exception $e ) {
    
//rollback

Saludos.

Hola GatorV, esto mismo había pensado yo, desde la propia función o método según el enfoque, levanto una excepción con el mensaje capturado del motor de bd....y funciona impeque, otro motivo para seguir en php 5 .

Con respecto a enrique, si bien es cierto hacer un wrapper de cada función no es tan complejo, tengo la siguiente duda.

¿Bastaría solo con las funciones que se utilizan en el proyecto?, ¿o sería necesario todas las funciones wrappeadas (así se escribe...) de la librería en cuestión?


Saludos .-
  #15 (permalink)  
Antiguo 28/07/2008, 20:34
 
Fecha de Ingreso: enero-2007
Mensajes: 272
Antigüedad: 17 años, 4 meses
Puntos: 5
Respuesta: Control elegante de transacciones

Cita:
Iniciado por Lord Kazuky Ver Mensaje
Saludos!

Bueno hasta este momento yo he venido utilizando dos métodos del objeto sobre el cual se efectua el proceso.

Un método de tipo público (para este caso podria llamarse 'grabarCompra' o 'grabar') que inicia la transacción, y hace el commit o rollback segun se termine o no satisfactoriamente el proceso de grabar la Compra

Un metodo de tipo privado (por ejemplo 'procesoGrabarCompra' o 'procesoGrabar') que es el que hace todas las validaciones necesarias, realiza todo el 'trabajo sucio' y devuelve un valor verdadero o falso segun se pueda terminar o no el proceso satisfactoriamente.
Me gusta esta forma, tener su clase para tener datos relacionados a lo que se hace, agregando lo que dice enrique y además el control de excepciones, quedaría bastante bien.
  #16 (permalink)  
Antiguo 28/07/2008, 22:04
Avatar de GatorV
$this->role('moderador');
 
Fecha de Ingreso: mayo-2006
Ubicación: /home/ams/
Mensajes: 38.567
Antigüedad: 18 años
Puntos: 2135
Respuesta: Control elegante de transacciones

Lo ideal es que sean "todas", pero no siempre es posible, así que lo que más puedas abstraer creo es lo mejor.

Saludos.
  #17 (permalink)  
Antiguo 28/07/2008, 23:09
Avatar de enriqueplace  
Fecha de Ingreso: mayo-2005
Ubicación: Uruguay / Argentina
Mensajes: 1.102
Antigüedad: 19 años
Puntos: 32
Respuesta: Control elegante de transacciones

Cita:
Iniciado por lucasarts_18 Ver Mensaje
Con respecto a enrique, si bien es cierto hacer un wrapper de cada función no es tan complejo, tengo la siguiente duda.

¿Bastaría solo con las funciones que se utilizan en el proyecto?, ¿o sería necesario todas las funciones wrappeadas (así se escribe...) de la librería en cuestión?
En primera instancia todas las que uses.... la idea es que no las uses de forma directa, pero tampoco tienes que implementar todos los métodos si no los necesitas.
__________________
Blog phpsenior.com Cursos a Distancia surforce.com
  #18 (permalink)  
Antiguo 29/07/2008, 09:37
Avatar de Lord Kazuky  
Fecha de Ingreso: junio-2006
Ubicación: 7F.00.00.01
Mensajes: 123
Antigüedad: 17 años, 10 meses
Puntos: 5
Respuesta: Control elegante de transacciones

El dilema esta (hablando en terminos generales) en que el abstraerse más implica más codigo separado (metodos, clases, etc..), y el desarrollo de un simple sistema puede volverse demasiado complejo. Creo que hay que saber hasta que punto se necesita abstraerse.

La ventaja es que el tiempo invertido en abstracción se ve recuperado en los cambios o mantenimiento del sistema y en el desarrollo de otros sistemas que reutilicen lo que ya se ha hecho.

Entonces pensaría en abstraer lo que sea útil abstraer, lo que se pueda reutilizar o lo que se considere que pueda cambiar a futuro.
__________________
Saludos.
"Cualquier tonto puede escribir código que un computador entiende. Los buenos programadores escriben código que los humanos pueden entender. ;)"
  #19 (permalink)  
Antiguo 29/07/2008, 09:40
Avatar de GatorV
$this->role('moderador');
 
Fecha de Ingreso: mayo-2006
Ubicación: /home/ams/
Mensajes: 38.567
Antigüedad: 18 años
Puntos: 2135
Respuesta: Control elegante de transacciones

He ahí la importancia de usar un buen Framework, que nos permita enfocarnos a la tarea especifica y no dar vueltas en cosas como esta.

Saludos.
  #20 (permalink)  
Antiguo 29/07/2008, 13:50
Avatar de Quest  
Fecha de Ingreso: diciembre-2002
Ubicación: Santiago
Mensajes: 129
Antigüedad: 21 años, 5 meses
Puntos: 2
Respuesta: Control elegante de transacciones

Cita:
Iniciado por GatorV Ver Mensaje
He ahí la importancia de usar un buen Framework, que nos permita enfocarnos a la tarea especifica y no dar vueltas en cosas como esta.

Saludos.
100% de acuerdo, si ya existe algo, que funciona y funciona bien, para que hacerlo nuevamente y mas encima intentar hacerlo sin los conocimientos necesarios.

Saludos
__________________
http://victorsanmartin.com
Web Developer
http://www.guiasitios.cl
Atención: Estás leyendo un tema que no tiene actividad desde hace más de 6 MESES, te recomendamos abrir un Nuevo tema en lugar de responder al actual.
Respuesta




La zona horaria es GMT -6. Ahora son las 13:56.