Foros del Web » Programando para Internet » PHP »

Probemas con Transacciones (COMMIT y ROLLBACK) en PHP contra PostgreSQL

Estas en el tema de Probemas con Transacciones (COMMIT y ROLLBACK) en PHP contra PostgreSQL en el foro de PHP en Foros del Web. Bueno, días tengan todos amigos. Les comento mi problema. Tengo un Formulario donde deseo hacer antes de mostrar el formulario al usuario un almacenamiento previo ...
  #1 (permalink)  
Antiguo 21/05/2010, 10:25
Avatar de jgabrielsinner10  
Fecha de Ingreso: octubre-2008
Mensajes: 26
Antigüedad: 16 años, 1 mes
Puntos: 0
Probemas con Transacciones (COMMIT y ROLLBACK) en PHP contra PostgreSQL

Bueno, días tengan todos amigos. Les comento mi problema. Tengo un Formulario donde deseo hacer antes de mostrar el formulario al usuario un almacenamiento previo del registro al cual referencia este formulario. Pero, lo hago en medio de una transacción es decir, mando el BEGIN WORK; seguido del INSERT RETURNING del registro y luego en seguida sin cerrar la transacción muestro el formulario con los datos registrados en transacción (no regsitrados permanentemente porque no he hehco commit) y a su vez retornados. Luego cuando el usuario edita los datos de este registro y le dá al botón submit envia estos datos a una pagina donde ejecuto el COMMIT de la transacción anterior, el problema está en que no hace el COMMIT bueno si ejecuta la sentencia pero, no se inserta el registro permanentemente
igual si le doy al botón de cancelar lo envío a una página que ejecuta un ROLLBACK.

After I'll write the code....


************************************************** **************
Archivo conexion.php
Código:
class Conexion {
	
	public static $RDBMS = "PostgreSQL";
	public static $id_conn;
	private static $dir_serv = "localhost"; //"localhost"
	private static $port = "5432";
	private static $user = "postgres"; // "postgres"
	private static $passw = "postgres"; // "postgres"
	private static $database = "invfact_db";
	public static $mailadmin = "";
	public static $sql;
	public static $last_sql;
	public $records = 10;
	public $pages = 5;
	
	function __construct() {
		$this->db_name = self::$database;
		$this->db_user = self::$user;
		$this->db_pass = self::$passw;
		$this->db_host = self::$dir_serv; //conexion directa al servidor
		self::getConnection ();
	}
	
	/**
	 * Obtiene una conexión
	 *
	 * @return Conección
	 */
	public static function getConnection() {
		$str_conexion = "host=" . self::$dir_serv . " port=" . self::$port . " dbname=" . self::$database . " user=" . self::$user . " password=" . self::$passw ;
		//echo $str_conexion;
		if(!isset(self::$id_conn) || pg_connection_busy(self::$id_conn)){
		
			if (! (self::$id_conn = pg_pconnect ( $str_conexion ))) {
				echo "<div align='center' id=\"error_bd\" style=\"color:#990000\" aling='center'><b>ERROR: Conectando a la Base de Datos.<br>" . utf8_encode(pg_errormessage ()) . "</b></div>";
				return FALSE;
			}
		
		}
		echo "<br />".pg_get_pid(self::$id_conn)."<br />";
		return self::$id_conn;
	}
	
	/**
	 * Ejecuta una sentencia SQL en la Base de 	Datos
	 *
	 * @param StringSQL $string_query
	 * @return Resource
	 */
	public function executeQuery($string_query) {
		$query_result = FALSE;
		if (func_num_args () != 1) {
			$query_result = FALSE;
		} else {
			self::$last_sql = $string_query;
			self::$id_conn = self::getConnection ();
			//echo "<br><br><b style='color: #990000'>".$string_query."</b><br/><br/>";
			//$query_result = TRUE;
			$query_result = pg_query ( self::$id_conn, $string_query );
		}
		return $query_result;
	}	
	
	/**
	 * Maneja el ciclo de vida de una Transacción
	 *
	 * @param String $operacion
	 * @return Resource
	 * 
	 */
	function managerTransaction($operacion){
		if(func_num_args()==1){
			$operacion = strtolower($operacion);
			if($operacion=="begin"){
				return $this->executeQuery("BEGIN WORK; ");
			}
			elseif ($operacion=="commit"){
				return $this->executeQuery(" COMMIT;");
			}
			elseif ($operacion=="rollback") {
				return $this->executeQuery(" ROLLBACK;");;
			}
			elseif ($operacion=="end") {
				return $this->executeQuery(" END WORK;");;
			}
			else {
				return FALSE;
			}
		}
		else{
			return FALSE;
		}
	}
}
(ojó esto e suna prueba en mi código nunca ejecutaría una sentencia sql en un controlador, ni tampoco mostraría codigo html en el controlador)


************************************************** **************
Archivo index.php
Código:
<?php
	session_start();
	require_once '../../core/conexion.php';
	$conexion = @new Conexion();
	
	$_SESSION["conexion_obj"] = serialize($conexion);
	
	$conexion->managerTransaction("BEGIN");
		$rs = $conexion->executeQuery("INSERT INTO public.prueba (prueba1, prueba2) VALUES ('HOLA1', 'CHAO1') RETURNING id_prueba, prueba1, prueba2;");
	$registros = $conexion->extraerRegistro($rs,"array");
	echo "<br />".print_r($registros)."<br />";
	
	if($rs){
		
?>
<br />
<div style="text-align: center">
	<form action="succes.php" method="get">
		<input type="hidden" name="id_prueba" id="id_prueba" value="<?php echo $registros["id_prueba"]; ?>">
			Prueba 1 : <input type="text" name="prueba1" id="prueba1" value="<?php echo $registros["prueba1"]; ?>">
		<br /><br />
			Prueba 2 : <input type="text" name="prueba2" id="prueba2" value="<?php echo $registros["prueba2"]; ?>">
		<br /><br />
			<input type="button" onclick="window.location.href = 'cancelar.php';" name="enviar" value="Cancelar">
		<br /><br />
			<input type="submit" name="enviar" value="Actualizar Datos">
	</form>
</div>
<?php 
	}
?>
************************************************** **************
Archvo succes.php
Código:
<?php
	session_start();
	require_once '../../core/conexion.php';
	$conexion = unserialize($_SESSION["conexion_obj"]);
	
	echo "<br />".pg_get_pid(Conehttp://static.forosdelweb.com/images/editor/color.gifxion::$id_conn)."<br />";

	      //$conexion->managerTransaction("BEGIN");
		  
	$rs = $conexion->managerTransaction("COMMIT");
	      $conexion->managerTransaction("END");
	
	if($rs):	
?>
	<div style="text-align: center">
		TODO FINO
	</div>
<?php else: ?>
	<div style="text-align: center">
		TODO MAL
	</div>
<?php endif;?>
Archivo Cancelar
Código:
<?php
	session_start();
	require_once '../../core/conexion.php';
	$conexion = unserialize($_SESSION["conexion_obj"]);
	
	echo "<br />".pg_get_pid(Conexion::$id_conn)."<br />";
	
         //$conexion->managerTransaction("BEGIN");

                  
	$rs = $conexion->managerTransaction("ROLLBACK");
		  $conexion->managerTransaction("END");
	
	if($rs):	
?>
	<div style="text-align: center">
		SE CANCEL&Oacute;
	</div>
<?php else: ?>
	<div style="text-align: center">
		EEEE NO SE
	</div>
<?php endif;?>
Cómo ven en alguna parte coloqué texto en azul para que vieran donde estoy haciendo la transacción... y además vean que estoy manteniendo el mismo objeto en session para mantener el id de conexión y así la base de datos PostgreSQL me reconózca la transacción (Pero, no lo hace). Necesito hacer este insert previo porque el formulario que estoy haciendo necesita el id de este registro en la misma pantalla... Por ahora estoy marcando este registro con un estatus de precarga y con un id de session php y luego lo actualizo con estatus de cargado y con el id que cerró dicho registro. estoy simulando acá un COMMIT pero, quisiera poder hacerlo de tal forma que la base de datos pudiera hacerlo automáticamente... Espero me puedan ayudar de verdad.

Muchas Gracias a todos de antemano

Posted By. José Gabriel González.

Última edición por jgabrielsinner10; 21/05/2010 a las 11:25
  #2 (permalink)  
Antiguo 21/05/2010, 10:28
Avatar de abimaelrc
Colaborador
 
Fecha de Ingreso: mayo-2009
Ubicación: En el planeta de Puerto Rico
Mensajes: 14.734
Antigüedad: 15 años, 6 meses
Puntos: 1517
Respuesta: Probemas con Transacciones (COMMIT y ROLLBACK) en PHP contra PostgreSQL

Dato adicional en lo que recibes respuesta, ¿Por qué mejor no usas PDO?
__________________
Verifica antes de preguntar.
Los verdaderos amigos se hieren con la verdad, para no perderlos con la mentira. - Eugenio Maria de Hostos
  #3 (permalink)  
Antiguo 21/05/2010, 10:31
Avatar de GatorV
$this->role('moderador');
 
Fecha de Ingreso: mayo-2006
Ubicación: /home/ams/
Mensajes: 38.567
Antigüedad: 18 años, 6 meses
Puntos: 2135
Respuesta: Probemas con Transacciones (COMMIT y ROLLBACK) en PHP contra PostgreSQL

El problema es que no entiendes mucho de como se maneja PHP, recuerda que PHP es un lenguaje que se ejecuta en el servidor y su tiempo de "vida" es durante un solo request.

Ahora PHP incluye varios garbage collectors, que cierran las conexiones abiertas al finalizar el script.

Si meditas esto puedes ver porque no puedes tener una transacción que "dure" durante varios requests, ya que al final del primer request se va a cerrar y la transacción se va a cerrar.

La idea de las transacciones es que se ejecuten en el mismo ámbito de tu request, y ahi controles los errores.

Saludos.
  #4 (permalink)  
Antiguo 21/05/2010, 10:59
Avatar de jgabrielsinner10  
Fecha de Ingreso: octubre-2008
Mensajes: 26
Antigüedad: 16 años, 1 mes
Puntos: 0
Respuesta: Probemas con Transacciones (COMMIT y ROLLBACK) en PHP contra PostgreSQL

abimaelrc brother gracias estoy investigando eso de usar PDO con PostgreSQL. Por otra parte GatorV hasta donde yo conózco pienso lo mismo que tu bro pero, se me ha requerido hacerlo de esta forma. Si con PDO se puede hacer les aviso.

Full gracias a ambos.

Última edición por jgabrielsinner10; 22/05/2010 a las 07:41
  #5 (permalink)  
Antiguo 21/05/2010, 11:06
Avatar de abimaelrc
Colaborador
 
Fecha de Ingreso: mayo-2009
Ubicación: En el planeta de Puerto Rico
Mensajes: 14.734
Antigüedad: 15 años, 6 meses
Puntos: 1517
Respuesta: Probemas con Transacciones (COMMIT y ROLLBACK) en PHP contra PostgreSQL

Si lo que deseas es hacer una revisión o algo por el estilo, puedes usar otra tabla para ingresar los datos y cuando corrobores entonces añades.
__________________
Verifica antes de preguntar.
Los verdaderos amigos se hieren con la verdad, para no perderlos con la mentira. - Eugenio Maria de Hostos
  #6 (permalink)  
Antiguo 21/05/2010, 11:25
Avatar de jgabrielsinner10  
Fecha de Ingreso: octubre-2008
Mensajes: 26
Antigüedad: 16 años, 1 mes
Puntos: 0
Respuesta: Probemas con Transacciones (COMMIT y ROLLBACK) en PHP contra PostgreSQL

Eeeeee... ya probé el código utilizando la clase PDO de PHP con PostgreSQL, pero, no ejecuta lo que yo quiero, sino que hace el mismo trabajo que hago con mi clase conexión, eso si el código es más elegante y no necesito un método managerTransaction ¿Cómo no?... muy buena idea abimaelrc.

Pero, se sigue cumpliendo lo que pensamos GatorV y yo. La transacción se pierde aunque mantega el mismo id de conexión.

Ojalá haya alguna forma en algún momento de hacer esto, ahorraría muuuuuchos procesos.

Posted By. José Gabriel González.
  #7 (permalink)  
Antiguo 21/05/2010, 11:27
Avatar de abimaelrc
Colaborador
 
Fecha de Ingreso: mayo-2009
Ubicación: En el planeta de Puerto Rico
Mensajes: 14.734
Antigüedad: 15 años, 6 meses
Puntos: 1517
Respuesta: Probemas con Transacciones (COMMIT y ROLLBACK) en PHP contra PostgreSQL

Bueno, como te comenté si deseas hacer revisiones puedes ir almacenando en una tabla (sea temporal o como quieras), haces los arreglos pertinentes basado en esa tabla y cuando quieras publicarla lo envías a otro código para que se ejecute en todo el request.
__________________
Verifica antes de preguntar.
Los verdaderos amigos se hieren con la verdad, para no perderlos con la mentira. - Eugenio Maria de Hostos
  #8 (permalink)  
Antiguo 21/05/2010, 11:35
Avatar de GatorV
$this->role('moderador');
 
Fecha de Ingreso: mayo-2006
Ubicación: /home/ams/
Mensajes: 38.567
Antigüedad: 18 años, 6 meses
Puntos: 2135
Respuesta: Probemas con Transacciones (COMMIT y ROLLBACK) en PHP contra PostgreSQL

Exacto vas a tener que "emular" la transacción, guardando los datos en una tabla temporal y solo hasta "confirmar" el proceso los mueves a su ubicación final, y en caso de cancelar simplemente borras el dato de la tabla temporal.
  #9 (permalink)  
Antiguo 21/05/2010, 11:46
Avatar de jgabrielsinner10  
Fecha de Ingreso: octubre-2008
Mensajes: 26
Antigüedad: 16 años, 1 mes
Puntos: 0
Respuesta: Probemas con Transacciones (COMMIT y ROLLBACK) en PHP contra PostgreSQL

Ook perfecto...Si, este proceso me parece muy bueno ya que se mantiene el ACID. Muchas gracias de nuevo.

Etiquetas: commit, contra, postgresql, rollback, transacciones
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 19:10.