In order for this site to work correctly we need to store a small file (called a cookie) on your computer. Most every site in the world does this, however since the 25th of May 2011, by law we have to get your permission first. Please abandon the forum if you disagree.

Para que este foro funcione correctamente es necesario guardar un pequeño fichero (llamado cookie) en su ordenador. La mayoría de los sitios de Internet lo hacen, no obstante desde el 25 de Marzo de 2011 y por ley, necesitamos de su permiso con antelación. Abandone este foro si no está conforme.

Bloqueo de registros usando TWebDataSource

Foro público de Xailer en español
Responder
PEDRO DE LEON RODAS[3]
Mensajes: 266
Registrado: Mar Oct 28, 2008 4:41 am

Bloqueo de registros usando TWebDataSource

Mensaje por PEDRO DE LEON RODAS[3] »

Saludos a todos y cada uno.
La conexion en ambos modos funciona perfectamente bien.
Con TWebDataSource ya esta el archivo php en el hosting (servidor web)
Estoy intentando trabajar con conexion a mysql usando TWebDataSource a un
hosting, y me he encontrado con el detalle que no puedo hacer que un cierto
registro sea bloqueado por un usuario.
Sin embargo si uso TMariaDBDataSource, los bloqueos funcionan perfectamente
bien.
Pongo un ejemplo de como lo hago con TMariaDBDataSource.
METHOD VALIDA_CODIGO()
Local cCodigo_producto,cantidad_total
::cProductos:oDatasource=AppData:Base
cantidad_total=1
AppData:Base:Execute("SET AUTOCOMMIT=0")
AppData:base:BeginTrans()
::cProductos:cSelect="Select id,codigo,descripcion,existencia_actual from
productos where codigo='"+cCodigo_producto+"' FOR UPDATE " /// AQUI HAGO
LA CONSULTA PARA OBTENER LAS EXISTENCIAS ACTUALES DEL PRODUCTO, AL HACER
ESTO NO DEJA QUE OTRO USUARIO
CONSULTE O EDITE LA TABLA PRODUCTOS
::cProductos:lOpen=.t.
/// AQUI EDITO LA TABLA PRODUCTOS Y ACTUALIZO LAS EXISTENCIAS ACTUALES DEL
PRODUCTO
::cProductos:EDit()
::cProductos:Salidas=::cProductos:Salidas+cantidad_total
::cProductos:existencia_actual=::cProductos:existencia_actua l-cantidad_total
::cProductos:Update()
/// AQUI CIERRO LA TRANSACCION Y SE DESBLOQUEA EL REGISTRO
AppData:Base:CommitTrans()
AppData:Base:Execute("SET AUTOCOMMIT=1")
RETURN Nil
ESTE PROCEDIMIENTO FUNCIONA MUY BIEN, ME BLOQUEA LOS REGISTROS SIN NINGUN
PROBLEMA
PONGO UN EJEMPLO DE COMO LO ESTOY USANDO CON TWebDataSource
METHOD VALIDA_CODIGO()
Local cCodigo_producto,cantidad_total
::cProductos:oDatasource=AppData:Base
cantidad_total=1
AppData:Base:Execute("SET AUTOCOMMIT=0")
AppData:base:Execute("Begin")
::cProductos:cSelect="Select id,codigo,descripcion,existencia_actual from
productos where codigo='"+cCodigo_producto+"' FOR UPDATE " /// AQUI HAGO
LA CONSULTA PARA OBTENER LAS EXISTENCIAS ACTUALES DEL PRODUCTO, AL HACER
ESTO NO DEJA QUE OTRO USUARIO
CONSULTE O EDITE LA TABLA PRODUCTOS
::cProductos:lOpen=.t.
/// AQUI EDITO LA TABLA PRODUCTOS Y ACTUALIZO LAS EXISTENCIAS ACTUALES DEL
PRODUCTO
::cProductos:EDit()
::cProductos:Salidas=::cProductos:Salidas+cantidad_total
::cProductos:existencia_actual=::cProductos:existencia_actua l-cantidad_total
::cProductos:Update()
/// AQUI CIERRO LA TRANSACCION Y SE DESBLOQUEA EL REGISTRO
AppData:Base:Execute("Commit")
AppData:Base:Execute("SET AUTOCOMMIT=1")
RETURN Nil
CON TWEBDATASOURCE NO FUNCIONA EL BLOQUEO
Por toda ayuda que me proporcionen, gracias.
Avatar de Usuario
jfgimenez
Site Admin
Mensajes: 5706
Registrado: Lun Abr 06, 2015 8:48 pm
Contactar:

Bloqueo de registros usando TWebDataSource

Mensaje por jfgimenez »

Pedro,
en principio deberí­an funcionar ambas igual. TWebDatasource no modifica
la sentencia que pongas, y en especial no quita la cláusula "FOR
UPDATE". Quizás el problema está en la tabla en sí­ y en cómo se ha
creado. Si no me equivoco, los bloqueos están soportados por InnoDB,
pero no por otros motores de almacenamiento de MySQL/MariaDB, como
MyIsam (que no soporta transacciones). Comprueba qué motor de
almacenamiento está usando esa tabla.
Un saludo,
José F. Giménez
http://www.xailer.com
http://www.xailer.info
José F. Giménez
[Equipo de Xailer / Xailer team]
http://www.xailer.com
http://www.xailer.info
PEDRO DE LEON RODAS[3]
Mensajes: 266
Registrado: Mar Oct 28, 2008 4:41 am

Bloqueo de registros usando TWebDataSource

Mensaje por PEDRO DE LEON RODAS[3] »

Jose, gracias por tu pronta respuesta.
Te comento, en ambos metodos acceso al mismo hosting y a la misma base de
datos.
Mis tablas tienen el tipo de InnoDB.
Usando TMariaDBDataSource funciona bien los bloqueos.
Usando TWebDataSource no me funcionan los bloqueos.
Gracias.
Saludos.
"Jose F. Gimenez" escribió en el mensaje de
noticias:[email=5381be7d@svctag-j7w3v3j....]5381be7d@svctag-j7w3v3j....[/email]
Pedro,
en principio deberí­an funcionar ambas igual. TWebDatasource no modifica
la sentencia que pongas, y en especial no quita la cláusula "FOR
UPDATE". Quizás el problema está en la tabla en sí­ y en cómo se ha
creado. Si no me equivoco, los bloqueos están soportados por InnoDB,
pero no por otros motores de almacenamiento de MySQL/MariaDB, como
MyIsam (que no soporta transacciones). Comprueba qué motor de
almacenamiento está usando esa tabla.
Un saludo,
José F. Giménez
http://www.xailer.com
http://www.xailer.info
Avatar de Usuario
ignacio
Site Admin
Mensajes: 9253
Registrado: Lun Abr 06, 2015 8:00 pm
Ubicación: Madrid, Spain
Contactar:

Bloqueo de registros usando TWebDataSource

Mensaje por ignacio »

Buenos dí­as,
Utilice el método BulkExecute. No hay otra forma. Piense que cada operación que realice con el motor de BD es un cursor nuevo y por lo tanto es imposible hacer cierto tipo de operaciones. Por dicho motivo existe BulkExecute. Si su código se complica utilice procedimientos almacenados.
Un saludo
Ignacio Ortiz de Zúñiga
[Equipo de Xailer / Xailer team]
https://www.xailer.com
PEDRO DE LEON RODAS[3]
Mensajes: 266
Registrado: Mar Oct 28, 2008 4:41 am

Bloqueo de registros usando TWebDataSource

Mensaje por PEDRO DE LEON RODAS[3] »

Ignacio, saludos.
Gracias por su pronta respuesta.
He estado tratando de implentar lo que usted me recomendo hacer, pero al
usar BulkExecute me da el siguiente error.
Y perdon por mi ignorancia en este tema, posiblemente no esoy usando el
metodo correcto.
Si no es mucho pedir, podria usted apoyarme con un ejemplo en el uso de
BulkExecute, o como hacer la consulta y como insertar o actualizar
registros.
Por su apoyo, mil gracias
"Ignacio Ortiz de Zúñiga" escribió en el mensaje de
noticias:53830010$[email=1@svctag-j7w3v3j....]1@svctag-j7w3v3j....[/email]
Buenos dí­as,
Utilice el método BulkExecute. No hay otra forma. Piense
que cada operación que realice con el motor de BD es un
cursor nuevo y por lo tanto es imposible hacer cierto tipo
de operaciones. Por dicho motivo existe BulkExecute. Si su
código se complica utilice procedimientos almacenados.
Un saludo
--
Ignacio Ortiz de Zúñiga
[Equipo de Xailer/Xailer team]
http://www.xailer.com
http://www.xailer.info
PEDRO DE LEON RODAS[3]
Mensajes: 266
Registrado: Mar Oct 28, 2008 4:41 am

Bloqueo de registros usando TWebDataSource

Mensaje por PEDRO DE LEON RODAS[3] »

Este es el error que me da.
AEVAL(0)
Error BASE/2017 Argument error: AEVAL
Argumentos: ( [ 1] = Tipo: C Valor: Update productos set
existencia_inicial=existencia_actual+10 where tienda='CUERNAVACA' and
codigo='TAE' [ 2] = Tipo: B Valor: {|| ... })
"PEDRO DE LEON RODAS" escribió en el mensaje de
noticias:53836ce3$[email=1@svctag-j7w3v3j....]1@svctag-j7w3v3j....[/email]
Ignacio, saludos.
Gracias por su pronta respuesta.
He estado tratando de implentar lo que usted me recomendo hacer, pero al
usar BulkExecute me da el siguiente error.
Y perdon por mi ignorancia en este tema, posiblemente no esoy usando el
metodo correcto.
Si no es mucho pedir, podria usted apoyarme con un ejemplo en el uso de
BulkExecute, o como hacer la consulta y como insertar o actualizar
registros.
Por su apoyo, mil gracias
"Ignacio Ortiz de Zúñiga" escribió en el mensaje de
noticias:53830010$[email=1@svctag-j7w3v3j....]1@svctag-j7w3v3j....[/email]
Buenos dí­as,
Utilice el método BulkExecute. No hay otra forma. Piense
que cada operación que realice con el motor de BD es un
cursor nuevo y por lo tanto es imposible hacer cierto tipo
de operaciones. Por dicho motivo existe BulkExecute. Si su
código se complica utilice procedimientos almacenados.
Un saludo
--
Ignacio Ortiz de Zúñiga
[Equipo de Xailer/Xailer team]
http://www.xailer.com
http://www.xailer.info
Avatar de Usuario
jfgimenez
Site Admin
Mensajes: 5706
Registrado: Lun Abr 06, 2015 8:48 pm
Contactar:

Bloqueo de registros usando TWebDataSource

Mensaje por jfgimenez »

Pedro,
> Este es el error que me da.
> AEVAL(0)
>
> Error BASE/2017 Argument error: AEVAL
> Argumentos: ( [ 1] = Tipo: C Valor: Update productos set
> existencia_inicial=existencia_actual+10 where tienda='CUERNAVACA' and
> codigo='TAE' [ 2] = Tipo: B Valor: {|| ... })
El argumento de BulkExecute() es un array de sentencias, incluso aunque
sólo quieras ejecutar una. P.ej.:
::oWebDatasource:BulkExecute( { "SELECT ...." }, {"UPDATE ...."} )
Por cierto, he encontrado esto:
http://www.php.net/manual/es/pdo.transactions.php
Fí­jate especialmente en el párrafo que hay entre los dos bloques en
rojo. Lo que viene a decir, más o menos, es que si queda una transacción
pendiente cuando termina el script PHP, entonces dicha transacción es
anulada.
En el caso que planteas, lo que te está ocurriendo es exactamente eso.
Cada vez que llamas al método Execute() del webdatasource, se ejecuta el
correspondiente módulo PHP en el servidor. Y claro, se ejecuta y
termina, antes de que tu programa continúe, provocando la cancelación de
la transacción. Por lo tanto, la solución es la que te ha indicado
Ignacio, pero asegurándote de que todas las sentencias las incluyes en
una sola llamada a BulkExecute(), para que se ejecuten todas en un mismo
paso en el servidor.
Un saludo,
José F. Giménez
http://www.xailer.com
http://www.xailer.info
José F. Giménez
[Equipo de Xailer / Xailer team]
http://www.xailer.com
http://www.xailer.info
PEDRO DE LEON RODAS[3]
Mensajes: 266
Registrado: Mar Oct 28, 2008 4:41 am

Bloqueo de registros usando TWebDataSource

Mensaje por PEDRO DE LEON RODAS[3] »

Jose, muchas gracias por tu respuesta y por aclarar mis dudas.
Hice unas pruebas y al parecer si me funciona el bloqueo.
PREGUNTA
por lo que veo y entiendo es que No es necesario usar begin y commit
(iniciar y cerrar transaccion) ?
Este es el codigo que uso en las pruebas
AppData:Base:BulkExecute( {"update productos set
EXISTENCIA_ACTUAL=EXISTENCIA_ACTUAL+1 where codigo='"+::Codigo:Value+"' "} )
Seguire haciendo pruebas.
Nuevamente, gracias.
Saludos.
"Jose F. Gimenez" escribió en el mensaje de
noticias:53837833$[email=1@svctag-j7w3v3j....]1@svctag-j7w3v3j....[/email]
Pedro,
> Este es el error que me da.
> AEVAL(0)
>
> Error BASE/2017 Argument error: AEVAL
> Argumentos: ( [ 1] = Tipo: C Valor: Update productos set
> existencia_inicial=existencia_actual+10 where tienda='CUERNAVACA' and
> codigo='TAE' [ 2] = Tipo: B Valor: {|| ... })
El argumento de BulkExecute() es un array de sentencias, incluso aunque
sólo quieras ejecutar una. P.ej.:
::oWebDatasource:BulkExecute( { "SELECT ...." }, {"UPDATE ...."} )
Por cierto, he encontrado esto:
http://www.php.net/manual/es/pdo.transactions.php
Fí­jate especialmente en el párrafo que hay entre los dos bloques en
rojo. Lo que viene a decir, más o menos, es que si queda una transacción
pendiente cuando termina el script PHP, entonces dicha transacción es
anulada.
En el caso que planteas, lo que te está ocurriendo es exactamente eso.
Cada vez que llamas al método Execute() del webdatasource, se ejecuta el
correspondiente módulo PHP en el servidor. Y claro, se ejecuta y
termina, antes de que tu programa continúe, provocando la cancelación de
la transacción. Por lo tanto, la solución es la que te ha indicado
Ignacio, pero asegurándote de que todas las sentencias las incluyes en
una sola llamada a BulkExecute(), para que se ejecuten todas en un mismo
paso en el servidor.
Un saludo,
José F. Giménez
http://www.xailer.com
http://www.xailer.info
Responder