Ver Mensaje Individual
  #1 (permalink)  
Antiguo 21/05/2010, 10:25
Avatar de jgabrielsinner10
jgabrielsinner10
 
Fecha de Ingreso: octubre-2008
Mensajes: 26
Antigüedad: 15 años, 6 meses
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