FTP | CCD | Buscar | Trucos | Trabajo | Foros |
|
Registrarse | FAQ | Miembros | Calendario | Guía de estilo | Temas de Hoy |
|
Herramientas | Buscar en Tema | Desplegado |
|
#1
|
|||
|
|||
Hola AI, gracias por tu aporte.
Cita:
Es totalmente aleatorio, pero si repaso, veo que las funciones que más se usan son las que más errores provocan. Pongo el trazado por si veis mas que yo El numero (1463 TMDOTransaction.Call) indica la linea donde se produce el error. Ahora mismo no tengo a mano el contenido de esa linea, pero lo pondré mañana.
Tengo el codigo fuente de los MDO, con la linea a la que hace referencia. Si puede servir para algo lo posteo. El problema al tratar de depurar, es que esos mismos procedimientos funcionan bien en otros equipos, incluso en el equipo ahora afectado llevaba 6 meses funcionando sin ningun problema. Incluso con la base de datos que da este error, estos procedimientos funcionan bien la mayoria de las veces, pero en ocasiones (cada hora de trabajo o más) empieza a dar fallos. Algunos de los forms del informe nunca se destruyen, otros se crean en ejecucion. Algunas de las querys que han dado error funcionan sin problemas desde hace años. No es que no pueda haber un error en mi codigo, solo que es muy raro, y parece haberse propagado por todas partes. Los MDO llevo 2 años usandolos sin problemas hasta ahora. Última edición por Sick boy fecha: 12-12-2008 a las 22:09:56. |
#2
|
||||
|
||||
Ojalá me equivoque pero... que yo sepa MDO lleva más de 1 año o 2 sin actualizarse, así que podría tratarse de no ser compatible con Firebird 2.
En un programa de prueba, con Firebird 1.5 funcionaba de lujo, con Firebird 2, me empezaba a dar errores de la API del motor . Yo elegí MDO porque estaban más avanzados que ZEOS en aquel momento, pero ahora ZEOS sigue actualizándose mientras que MDO se quedó estancado. Lamento dar este punto de vista pesimista... pero en fin, es mi opinión. Saludos y suerte
__________________
Si usted entendió mi comentario, contácteme y gustosamente, se lo volveré a explicar hasta que no lo entienda, Gracias. |
#3
|
|||
|
|||
Hola Lepe,
Si, es cierto que MDO lleva tiempo parado, bastante tiempo, y no parece que vaya a arrancar de nuevo. Acabo de revisar su web, parece que yo empece a trabajar con ellos justo cuando dejaron de actualizarlos Hasta ahora, me ha funcionado desde la 1.5 hasta la 2.1 sin ningun problema (bueno, salvo esto). Tras documentarme un poco más sobre ADO (solo habia hecho algo hace años para acces) no creo que sea la opcion que escoja si cambio de componentes. ZEOS son muy usados, y como dices, siguen actualizandose. Si cambiase los MDO probablemente fuera por los ZEOS. Una cosa de los ZEOS, por lo que he visto, no tienen componente para las transacciones, ni un dataset como el de MDO (aunque se puede suplir con un query y un updatequery). Las transacciones las gestiona automatico?? Cambia mucho la forma de trabajo con ZEOS?? Voy a repasar mi codigo y estudiar un poco del codigo de los MDO y pongo lo que encuentre. gracias por vuestra ayuda. Última edición por Sick boy fecha: 13-12-2008 a las 11:44:42. |
#4
|
|||
|
|||
Todo empieza aqui, este codigo se ejecuta sin problemas
Código:
procedure TMDOQuery.InternalOpen; begin ActivateConnection(); ActivateTransaction; QSelect.GenerateParamNames := FGenerateParamNames; SetPrepared(True); if DataSource <> nil then SetParamsFromCursor; SetParams; inherited InternalOpen; end; Código:
procedure TMDOCustomDataSet.InternalOpen; var SetCursor: Boolean; function RecordDataLength(n: Integer): Long; begin result := SizeOf(TRecordData) + ((n - 1) * SizeOf(TFieldData)); end; begin SetCursor := (GetCurrentThreadID = MainThreadID) and (Screen.Cursor = crDefault); if SetCursor then Screen.Cursor := crHourGlass; try ActivateConnection; ActivateTransaction; if FQSelect.SQL.Text = '' then MDOError(mdoeEmptyQuery, [nil]); if not FInternalPrepared then InternalPrepare; if (FQSelect.SQLType in [SQLSelect, SQLSelectForUpdate]) then begin if DefaultFields then CreateFields; BindFields(True); FCurrentRecord := -1; FQSelect.ExecQuery; ............. hay mas codigo, pero nos interesa hasta ExecQuery ........ Código:
procedure TMDOSQL.ExecQuery; var fetch_res: ISC_STATUS; begin CheckClosed; if not Prepared then Prepare; CheckValidStatement; if (FBase.Transaction.AutoCommit) and not (FBase.Transaction.InTransaction) then begin FBase.Transaction.StartTransaction; end; try case FSQLType of SQLSelect, SQLSelectForUpdate: begin Call(isc_dsql_execute2(StatusVector, TRHandle, @FHandle, Database.SQLDialect, FSQLParams.AsXSQLDA, nil), True); AQUI->> Call( isc_dsql_set_cursor_name(StatusVector, @FHandle, PChar(FCursor), 0), True); FOpen := True; FBOF := True; FEOF := False; FRecordCount := 0; if FGoToFirstRecordOnExecute then Next; end; // Removed the code FCursor set name from the TMDOSQL.Create. // This is needed because if you create the MDOSQL dynamically, the name is // not assigned in the create and the cursor is only based on a 'random' // number. And, in some special situation, duplicate cursornames will appear //FCursor := Name + RandomString(8); buffff, atentos a esto: "And, in some special situation, duplicate cursornames will appear" !!!!! Justo lo que me sucede ahora, ya que muchas querys las creo dinamicamente. Ya me gustaria saber cual es la "special situation" a la que se refieren.... Vale, ya tenemos localizado el problema, los creadores de MDO ya lo sabian, veamos como lo resolvieron.... Código:
procedure TMDOSQL.Prepare; var stmt_len: Integer; res_buffer: array[0..7] of Char; type_item: Char; begin if FCursor = '' then !! Parece que NO LO RESOLVIERON !!! FCursor := Name + RandomString(8); !! Utilizan el randomstring(8) igual que en el codigo editado en el constructor !! CheckClosed; FBase.CheckDatabase; FBase.CheckTransaction; if FPrepared then exit; if (FSQL.Text = '') then MDOError(mdoeEmptyQuery, [nil]); if not ParamCheck then ........ continua ...... Estas son las funciones que generan el nombre (numero) del cursor. Código:
function RandomString(iLength: Integer): String; begin result := ''; while Length(result) < iLength do result := result + IntToStr(RandomInteger(0, High(Integer))); if Length(result) > iLength then result := Copy(result, 1, iLength); end; function RandomInteger(iLow, iHigh: Integer): Integer; begin result := Trunc(Random(iHigh - iLow)) + iLow; end; Si no son seguras, se pueden mejorar??? Por otro lado, si el problema no es por la generacion del numero de cursor, entonces es que un cursor se queda "pillado", pero no se como puede ser posible. Los componentes MDO son los que se encargan de los cursores, creacion y destruccion, ¿de que modo podriamos dejar los cursores huerfanos en memoria provocando este error??? Espero que este post ayude a alguien que se encuentre en esta misma situacion, creo que he avanzado bastante en localizar el problema, un poco más y descubriremos que sucede realmente. |
#5
|
|||
|
|||
Cita:
Las transacciones de controlan con TZconnection, que es como un TDataBase + TTransaction. Pero, y si quiero tener más de una transaccion?? Hay que asignar un TZConnection por cada transaccion?? Por lo que he leido, las transacciones se pueden gestionar automatica o manualmente. |
#6
|
|||
|
|||
Código:
// Removed the code FCursor set name from the TMDOSQL.Create. // This is needed because if you create the MDOSQL dynamically, the name is // not assigned in the create and the cursor is only based on a 'random' // number. And, in some special situation, duplicate cursornames will appear //FCursor := Name + RandomString(8); yo de ti no perderia mas el tiempo con estos componentes. Ahora bien, si aun los quieres usar, puedes probar de, en el create del componente, asignar el nombre del cursor de una manera que a ti te convenga :ej, numero de componentes MDOSQL en la aplicacion o con el GetNamePath, asignando el nombre a cada MDOSQL que crees dinamicamente, o bien haciendo overload del create con un parametro de cursor. |
#7
|
|||
|
|||
Efectivamente, es una chapuza, si al menos hubieran dicho cuales son las condiciones especiales se podria tratar de evitarlas.
Parece que tendre que cambiar de componentes, pero mientras tanto, quisiera resolver esto y ganar un poco de tiempo. Afortunadamente, solo un cliente tiene esas condiciones especiales. No me atrevo a meterle mano al codigo de MDO, pero esta claro que de alguna manera debo modificar el nombre del cursor para hacerlo unico, pero no se como hacerlo. Cita:
GetNamePath parece mejor opcion. Esto funcionaria??: FCursor := self.getnamepath + RandomString(8); No es que no quiera probarlo yo mismo, es que me es muy dificil reproducir el error, en mis equipos no pasa. El overload, pues no tengo ni idea de como quedaria, en este punto necesitaria un ejemplo. Última edición por Sick boy fecha: 13-12-2008 a las 15:14:51. |
#8
|
||||
|
||||
Yo me reservo el derecho de criticar.
Para mí, una gente que trata directamente con la API de un SGBBDD y que dan al programador una interfaz al estilo de Interbase, ya se merecen mi respeto, si además lo hacen Open Source, un aplauso para ellos. Y ya ni hablar del elegante diseño de clases, jerarquías, calidad del código, etc. Existen componentes de pago (nada baratos) que sólo ver el código fuente se les debería caer la cara de vergüenza, al menos ese fallo, conceptualmente, no tiene mucha importancia (para Sick boy si lo tendrá porque le está amargando la existencia ). La generación de números aleatorios siempre han tenido ese fallo, pueden repetirse en "determinadas circunstancias". Dicho sea de paso, si la función random hiciera su trabajo bien, los MDO no fallarían . Saludos
__________________
Si usted entendió mi comentario, contácteme y gustosamente, se lo volveré a explicar hasta que no lo entienda, Gracias. |
|
|
Temas Similares | ||||
Tema | Autor | Foro | Respuestas | Último mensaje |
Mensaje de error extraño | Sick boy | Firebird e Interbase | 0 | 12-12-2008 11:22:26 |
Error Extraño | SysAdminGCS | Varios | 1 | 18-08-2007 16:30:49 |
Error Extraño | Esau | SQL | 4 | 17-06-2005 22:44:16 |
error extraño | gilberto_1126 | Varios | 2 | 05-09-2004 01:01:01 |
Error Extraño | Esau | OOP | 5 | 19-11-2003 18:01:32 |
|