#101 Re: mORMot 1 » Firebird transactions » 2014-12-18 06:56:14

@ttomas

Where can i download this FB-tracing app?

Looking to your results:
I'm starting from the premisse you do NOT use latest \testing-7.2 sources from SVN or latest mORMot?

Current mORMot starts a ReadCommited TIL. As i wrote several times: before latest patches Zeos did Never change the TIL. Using latest 7.2 from SVN Zeos closes the tpb_concurrency (FB default) TA and restarts a new TA with ReadCommited transaction behavior.
Also is it possible to change the HARD_COMMIT on the fly by settinge/dropping this Parameter to/from the ZURL.Properties.

To be clear and on same bandwidth: Please update mORMot and Zeos from SVN, resart your tracing and attach it again.


Michael

#102 Re: mORMot 1 » Firebird transactions » 2014-12-16 20:05:25

ttomas wrote:

Another bad behavior of ZeosDBO is Auto start of transaction. If you use connection pool you will have shifting of transaction logic, transaction is started in previous Unit of work and commited in current
...
This behavior can be confirmed with monitoring (trace) FB server.

? About which mode do we talk here? Did you set "hard_commit=true"? Else i can't confirm your findings? Subsequential transactions are NOT supported yet. There is no TA1, 2 or 3! Required savepoints e.g. FD-Docs are not implmented yet.

Note I'm NOT the initial autor of Zeos. Just want to support you guys as good as i can. The behavior is known since years. (Even if i know this is a show-stopper if you are not aware of that!)

Thinking about it .. might be a option for 7.3.. Not sure yet Loads of work is waiting for current 7.3 development..

@AB
are you talking about Daniel's issues? Hope i got it resolved inbetween...? Let's wait for reply.. I wouldn't start from the premisse the issue remains, Arnaud.

Michael

#103 Re: mORMot 1 » Firebird transactions » 2014-12-11 21:29:47

@ab

i did check you FireDAC implementation. I can not find the AutoCommit mode you're using for Zeos. But FD supports it too: http://docwiki.appmethod.com/appmethod/ … FireDAC%29

So comparing a non autocommit Component with a ZDBC which definitely commits after each update(because you want it), is like comparing a froot-store with a apple.
To be fair you should either remove the autocommit on Zeos (again you are always in transactional mode until you close the connection) or you're playing a fair game and implement the autocommit for FD too.

Note i did bug out last FB TIL issues. current 7.2 changes the TIL like you want to have it now. I also did test your suggested parameter: It kills the performance in AutoCommit+Batch-mode(it does commit the execute block after each execution but i want to handle the batch idea as !one! update and only one commit should follow. So i rolled back the patch today and let Zeos selve control the auto-commit mode.

Where i agree: Current ZDBC + FB can't create subsequential Transactions. Also you and your users should know if you're changing the TIL on the fly your statement-cache should be flushed before. See same link of FD.

Michael

#104 Re: mORMot 1 » Firebird transactions » 2014-12-01 10:42:07

Agree.

Note you kan kill the sweeper_cache issue by having a second "UPDATE"-connection.

Adding 'hard_commit=True' like

Your_SQLDBZEOSConnectionProperties.ZeosURL.Properties.Add('hard_commit=true');

The TIL of FB is you choise too:

(YourSQLDBConnection as TSQLDBZEOSConnection).Database.SetTransactionIsolation(YourTIL{Level: TZTransactIsolationLevel});
Zeos ZDbcIntfs.pas wrote wrote:

  {** Defines a transaction isolation level. }
  TZTransactIsolationLevel = (tiNone, tiReadUncommitted, tiReadCommitted,
    tiRepeatableRead, tiSerializable);

As i wrote in \testing-7.2 SVN the patch is available to do this.
tiNone allows you to define you custom tdb's by adding them to the URL.Properties too. See FireBird/Interbase doc's how to do that.

Michael

#105 Re: mORMot 1 » Firebird transactions » 2014-11-30 15:55:48

danielkuettner wrote:

But Michael suggest such a single connection for Fb because it has no performance loss and it's better for our deadlock problem.

Right, i've been trying to say that.

But don't forgett my previous post for all other Drivers.
AutoCommit for Zeos is connection bound. All subsequential bound update statments automatically commit on succcess if Conenction is in AutoCommit mode. So i'm starting from the premisse i'm thinking to much in Zeos-Code-Lines.. smile

alpinistbg wrote:

As far as I understand, Arnaud wants the following behaviour:

    Group of SQL statements can be enclosed into explicit transaction, i.e. Begin, Stmt1,...,StmtN, Commit/Rollback;

    Outside such explicit transactions, each SQL statement must be enclosed in its own implicit transaction, i.e. to be committed immediately;

Although the SQLite3, MSSQL and PostgreSQL works exactly that way, the Firebird works differently. It does not insert implicit Commits until somebody tell him to do so (isn't it for that AutoCommit?).

Right. But this you can do by hand and the server does encapsulates subsequentual stmt's to it's transaction.

Actually i've no idea how to do that with FB quickly and without breaking current beahior.
It definitally is possible do do that! You can create X trans_handle's (FireBird/Interbase API) but which stmt is owned by which handle needs to be controlled by Zeos/mORMot.
A problem we can't simply resolve with current generic implementations.

In addition you should know:

Zeos documention wrote:

After confirming the chanes made in a transaction by COMMIT or resetting them by ROLLLBACK the
transaction normally is going to be ended and an existing resultset of a query or stored procedure will be
discarded. These COMMITs and ROLLBACKs are called "hard" commit or "hard" rollback. By using the
ZEOS library this will become a little bit different. ZEOS keeps the resultset alive. This is achieved by closing
transaction with "soft" commits or "soft" rollbacks. All this is done by the TZConnection object. This method is
called retaining. The COMMIT and ROLLBACK commands are executed with the addition RETAINING.
Retaining causes the closing of the current transaction and immediately opening a new transaction with all
the data and resources (especially the resultset) of the "old" transaction.
Retaining becomes a problem if it is uses for huge tables. It constrains the internal cleanup mechanism of
firebird (garbage collection). This leads (because of the versioning and the multigenerational architecture of
Firebird) to a lot of old records that have to be kept but will not be needed anymore. This influences the
server's performanced in a negative way. A so called sweep would discard these old versions and improve
the performance. This sweep will only be executed by sending a "hard" COMMIT or ROLLBACK. The ZEOS
Library only executes these "hard" commands when ending the database connection (closing connection). It
is not possible to send them while a database connection is active. So the database connection should be
deactivated and immediately activated occasionally to achieve this performance improvement.

My last patch of yesterday improves this a bit: Change TIL from Current to a different and a "hard_commit" follows and FB cleans up data. But you should know cached-stmts are lost than or trying to do that may raise an Exception!

Michael

#106 Re: mORMot 1 » Firebird transactions » 2014-11-30 12:52:48

@AB

ab wrote:

1. AFAIK TSQLDBZEOSConnection.StartTransaction does not start any transaction.

Yes this is right! You are in a single transaction since Connect.
You anly can Commit/Rolback.

ab wrote:

We need the auto commit to be available.
I mean, if i execute INSERT without any previous StartTransaction, this INSERT should be committed immediately.
Isn't it what "autocommit" mean?
Then, if I call StartTransaction, then no transaction would be committed until explicitly Commit or Rollback is executed.
This is why

Yes i agree with the AutoCommit idea. BUT who controls this behavior?
If YOU set Zeos in AutoCommit mode -> Zeos does it by it's selves! Each update will be commited after execution.

What i'm trying to say: If AutoCommit is set for Zeos you don't need a explicit Commit call on your side.
In addition if you are controler about the commits also in AutoCommit mode -> Than use the suggestion of Daniel. There is no need Zeos and Your are doing the commit call, understand me?

Michael

#107 Re: mORMot 1 » Firebird transactions » 2014-11-30 10:10:10

AB wrote:

As far as I understood the ZDBC code, you need TransactIsolationLevel <> tiNone to have the transaction to be supported in the units.
Previous SetTransactionIsolation(tiNone) would in fact disable any transaction process.
So I guess the code I wrote above in http://synopse.info/forum/viewtopic.php … 935#p13935 would work as such for all providers?

FYI:
After reading all this here i did study the whole Connection interfaces about the Transactions..
NO you are allways in a transaction for ALL providers.
The transaction will be started right after open. For FB as well. But for FB + tiNone the Server starts the defaults. Also are you able to add Connection properties to start your own transaction kinds of FireBird.

May i ask how you handle the AutoCommit mode?
If you do it by your selves by slt:

  YourClass.Commit;

than the Autocommit is not required. And this may cause the DeadLock because if Zeos executes the Stmt a commit will be done if succeed (except for ExecuteQueryPrepared/ExecuteQuery of course). Don't know if FB has problems on calling a second commit?!

So i propose you follow Daniels suggestion.

#108 Re: mORMot 1 » Firebird transactions » 2014-11-29 23:20:46

@mpv

which info's do you need?

alpinistbg wrote:

no need of resetting/setting AutoCommit between StartTransaction/Commit

Yes this is right for Commit and Rollback. NOTHING would happen. So it's not perfekt but ok.

procedure TSQLDBZEOSConnection.StartTransaction;
begin
  inherited StartTransaction;
  fDatabase.SetAutoCommit(false);
end;

is correct to me. You're expecting a Transaction which YOU can commit or Rollback.

If i would know how everything works in AB's ORM (:  In the past he asked me if this code is correct.. If it's a pure retaining model than of course it is correct.

Aranud it might be a good idea to add a property

TSQLDBZEOSConnection = class(TSQLDBConnectionThreadSafe)
...
public
  ....
  TransactIsolationLevel: TZTransactIsolationLevel read f.... write SetTransactionIsolation;
 ....
end;
procdedure SetTransactionIsolation(Level: TZTransactIsolationLevel);
begin
  fDatabase.SetTransactionIsolation(tiReadCommitted);
 
end;

tiNone by default is still OK for me.

Agree the users should have free hand to choose the TIL.

Just study SetTransactionIsolation() in ech ZDbcXXXConnection.pas what the enums do represent.
For PostgreSQL f.e. tiNone is the simple 'BEGIN' call.

But ... I must admit i have to check how you can manipulate in FB?!

Edit: Now you can also customize your TIL's for FB. Patch done R3526 \testing-7.2 will be merged to trunk and \testing-7.3 in a periode of a week.

#109 Re: mORMot 1 » Integrating TDS in SynDBZeos » 2014-11-27 11:50:19

ab wrote:

This does make sense to me.
I was never attracted by the TDS clients...

Agree. Propose you simply add a comment to your documentations and close your ticket, if nobody has objections, of course.

Eventually some additional notes:

TDS is able to be used for all old SQL servers too (6.5-2012). I don't know if the ODBC driver can be used with them..
But let's say: All below 2000 are old and Mircosoft also did stop supporting them!

Michael

#110 Re: mORMot 1 » Integrating TDS in SynDBZeos » 2014-11-26 23:35:59

Arnaud,

i know we did loudly ask for this support... But i have to admit TDS is a dead and way from my point of view. Let me explain some advantage/disadvantage for your users:

Advantages:
1. one little library to access Sybase or MSSQL by using the "Tabular Data Stream" protocol: ntwdblib.dll/dblib.dll or a FreeTDS library.

Disadvantages:
1. MSSQL does not support a type difference between N(VAR)Char / (VAR)Char-Fields
2. All Strings which are retrieved need a encoding detection to indicate which encoding a column has -> what about native USASCII chars? -> Performance?
2. NTEXT fields are not selectable you need a cast to TEXT
3. NO Prepared Statement API. Zeos simply emulatates it.
4. MSSQL is doing no encoding detection: so the spezial syntax whould be required to indicate which param uses which encoding! NO WAY AROUND
5. The TDS protocol is sequential only. The more you have only one Connection handle. NOTHING else. SO if you guys are making a select, Zeos is forced cache ALL data. If this is done mORMot can get the JSON-Contents. This is done because next query kills a opened request...
6. All String columns are retrieved with ' '(Space)-filled strings. There is a mode "ANSI_PADDING=OFF/ON" which allows to enable/disable this behavior. Disabling means you will get a exception if you try to update a fixed-char field with a length shorter than Field.Length. Nice isn't it?

Should i go on? I don't think so.

Well it might be possible some more users do want to use it. So keep the ticked but note this is a very spezial case. From my point of view: No need to over hurry.

Michael

#111 Re: mORMot 1 » Firebird transactions » 2014-11-26 23:09:22

Arnaud,

whoops! Yep the user is right: tiNone for FireBird allows to set a user choosen TIL by adding parameters of:

  TransactionParams: array [0..MAX_TPB_PARAMS]of TZIbParam = (
    (Name:'isc_tpb_version1';         Number: isc_tpb_version1),
    (Name:'isc_tpb_version3';         Number: isc_tpb_version3),
    (Name:'isc_tpb_consistency';      Number: isc_tpb_consistency),
    (Name:'isc_tpb_concurrency';      Number: isc_tpb_concurrency),
    (Name:'isc_tpb_exclusive';        Number: isc_tpb_exclusive),
    (Name:'isc_tpb_shared';           Number: isc_tpb_shared),
    (Name:'isc_tpb_protected';        Number: isc_tpb_protected),
    (Name:'isc_tpb_wait';             Number: isc_tpb_wait),
    (Name:'isc_tpb_nowait';           Number: isc_tpb_nowait),
    (Name:'isc_tpb_read';             Number: isc_tpb_read),
    (Name:'isc_tpb_write';            Number: isc_tpb_write),
    (Name:'isc_tpb_ignore_limbo';     Number: isc_tpb_ignore_limbo),
    (Name:'isc_tpb_read_committed';   Number: isc_tpb_read_committed),
    (Name:'isc_tpb_rec_version';      Number: isc_tpb_rec_version),
    (Name:'isc_tpb_no_rec_version';   Number: isc_tpb_no_rec_version),
    (Name:'isc_tpb_lock_read';        Number: isc_tpb_lock_read),
    (Name:'isc_tpb_lock_write';       Number: isc_tpb_lock_write)
    );

To the connection properties. This was made to be able to handle all possible ISC_TPB modes FB supports.

ab wrote:

Within a transaction I suspect we could leave the default tiNone value since the transaction is explicit. Note: This is a FB single case...

Yep i would confirm that too.

#112 Re: mORMot 1 » Wow! Full FPC support now??!! » 2014-11-11 00:43:13

Well the report is marked as Resolved and fixed.
AFAIU the FPC bugtracker: Closing should be done by reporter. Else they keep the report a long time until a core member decides to close it.

So they are waiting for a confirmation or you can reopen same ticket if you disagree, Arnaud.

Just a hint. Maybe AOG can compile the trunk and test the fix? Or you kindly should close the report. This way all are happy.

#113 Re: mORMot 1 » Wow! Full FPC support now??!! » 2014-11-10 16:24:34

@AB

propose you reply a "thank you" and close the bugreport?..

#114 Re: mORMot 1 » Erro testing Samples\30 - MVC Server\MVCServerPostgreSQL » 2014-11-04 17:09:20

@corchi72

note:
You can't load a 64Bit dll with a 32Bit compiletarget. My error-message told you: The file was found but we can't load this lib!
C:\Program Files\ is propably the 64Bit directory.

This is also NO problem. Just download the 32Bit client from http://www.enterprisedb.com/postgresql- … =Crossover
This is NO installer since you've allready installed the 64Bit server. Then use the lib's of the zip. Best practice: Copy them to C:\windows\SYSWOW64 which is made for the !!!32Bit!!! libs. In addition copy the libs of your current installation to C:\Windows\system32 which is made for the !!!64Bit!!! DLL's. Delete all other approaches you made... have fun!

#115 Re: mORMot 1 » Erro testing Samples\30 - MVC Server\MVCServerPostgreSQL » 2014-11-04 15:05:53

@corchi72 again:

use the libraries of your PostgreSQL server. You can find them in ...\PostgreSQL\9.3\Bin
You're simply trying to access a protocol v3 server with deprecated protocol v2 libraries.

Michael

#116 Re: mORMot 1 » ZEOS+Postgresql CreateMultiIndex » 2014-11-04 13:18:10

An example please... So i can help from Zeos-side!

#117 Re: mORMot 1 » Erro testing Samples\30 - MVC Server\MVCServerPostgreSQL » 2014-11-04 13:16:55

@corchi72

corchi72 wrote:

I'm tested also with libpq74.dll /80.dll/81.dll

what's that? Use always the client-libs of your installtion!

#118 Re: mORMot 1 » mORMot.pas » 2014-10-30 12:21:31

@AOG

there is propably an aligment issue with ARM-processors.
FPC has a buildin define to control that behavior:

  MyRecord = {$ifndef FPC_REQUIRES_PROPER_ALIGNMENT}packed{$endif} record...

Note it might be possible you need dummy pointer alignments if pointers are used in the record sad

Don't know anything about delphi issues in this case..

#119 Re: mORMot 1 » CreateMissingTables does not create tables in external FirebirdDB » 2014-10-28 19:44:36

Note:

Zeos provides a huge ',' delimited String for SQLKeyWords in any kind:

IZConnection.GetMetadata.GetDatabaseInfo.GetSQLKeywords: String;

So you could prevent such issues...

Zeos FireBird wrote:

{**
  Gets a comma-separated list of all a database's SQL keywords
  that are NOT also SQL92 keywords.
  @return the list
}
function TZInterbase6DatabaseInfo.GetSQLKeywords: string;
begin
  Result := 'ACTIVE,AFTER,ASCENDING,BASE_NAME,BEFORE,BLOB,' +
    'CACHE,CHECK_POINT_LENGTH,COMPUTED,CONDITIONAL,CONTAINING,' +
    'CSTRING,DATABASE,RDB$DB_KEY,DEBUG,DESCENDING,DO,ENTRY_POINT,' +
    'EXIT,FILE,FILTER,FUNCTION,GDSCODE,GENERATOR,GEN_ID,' +
    'GROUP_COMMIT_WAIT_TIME,IF,INACTIVE,INPUT_TYPE,INDEX,' +
    'LOGFILE,LOG_BUFFER_SIZE,MANUAL,MAXIMUM_SEGMENT,MERGE, MESSAGE,' +
    'MODULE_NAME,NCHAR,NUM_LOG_BUFFERS,OUTPUT_TYPE,OVERFLOW,PAGE,' +
    'PAGES,PAGE_SIZE,PARAMETER,PASSWORD,PLAN,POST_EVENT,PROTECTED,' +
    'RAW_PARTITIONS,RESERV,RESERVING,RETAIN,RETURNING_VALUES,RETURNS,' +
    'SEGMENT,SHADOW,SHARED,SINGULAR,SNAPSHOT,SORT,STABILITY,STARTS,' +
    'STARTING,STATISTICS,SUB_TYPE,SUSPEND,TRIGGER,VARIABLE,RECORD_VERSION,' +
    'WAIT,WHILE,WORK,VALUE,POSITION,USER,CURRENCY,OPTION,DATE,START,END,USER,' +
    'READ,PARENT,TYPE'+
    {Ticket #63: http://sourceforge.net/p/zeoslib/tickets/62/}
    ',DEC,TIME,MIN,MAX'+
    {FireBird 3.0}
    ',DETERMINISTIC,OVER,RETURN,SCROLL,SQLSTATE';
end;

#120 Re: mORMot 1 » MVC/MVVM Web Applications with mORMot! » 2014-10-28 15:10:42

You can safely use both:

IZConnection.GetMetadata.ClearCache;

pesits since i know Zeos.

'NoTableInfoCache=true'

Is a String property which simply has no effect for older Revisions.

During the process only the TableInfoCache can grow the memory until all informations are collected. May i ask if FireBird behaves equal?

#121 Re: mORMot 1 » MVC/MVVM Web Applications with mORMot! » 2014-10-28 14:51:55

I suspect it has nothing to do with memory consumption during the process, right?

Hard to say. The two caches MAY consume loads of mem dependend to count of (GetTables + (GetColumns, GetPrimaryKeys/GetIndexInfo) per table)) x CountOf(Connections)
In addition there is the TableInfoCache for PostreSQL only.

So if i would know how this MVC samples do work, i could give you a true answer.. I'm wondering the memory grows during the process..
Propose you test it with multithreading and flushed caches? I would like to know results...

Edit: I really see nothing else which can produce such memory consuming behavior, Arnaud.

#122 Re: mORMot 1 » MVC/MVVM Web Applications with mORMot! » 2014-10-28 14:39:17

ab wrote:

So what we should we do in SynDBZeos?

Is http://synopse.info/fossil/info/ed5b4034df correct?

Looks like good start.

To be clear:
Am i right you're calling the Zeos-MetaInformations only once an CreateMissingTables?

If so than you can simply flush the cache by calling:

IZConnection.GetMetadata.ClearCache;

if CreateMissingTables is done. What do you think? You can execute it by default from my point of view..

#123 Re: mORMot 1 » MVC/MVVM Web Applications with mORMot! » 2014-10-28 14:08:17

That's cool. Looks like you also have a solution for everything.
Note accordingly stable behavior: There is NO difference to see. Just the cached data each connection uses grows the memory.

Anyway, i propose you add my suggested code and some comments to the ZeosDB files, just to notify users about the possibilities...

In addition.. IIRC are you calling the Zeos-MetaData only one on CreateMissingTables, right? So from my point of view the whole caching stuff makes no sence for your framework, Arnaud.
Think about it...

#124 Re: mORMot 1 » MVC/MVVM Web Applications with mORMot! » 2014-10-28 13:51:04

ab wrote:

This sadly did NOT fix the issue!
Now memory still grows, perhaps a little slower, but it quickly reached more than 1 GB.
Whereas FireDAC did use less than 20 MB AFAIR.

Use of PostgreSQL client consumes much more memory than SQLite3 itself, and more that the stored data. sad

I know that, but keeps temporary allocated memory much smaller on each GetUTF8String().

Note:
1. since your project works with threads and each thread has a new IZConnection the memory grows because of Cached metadata informations.
2. for PostgreSQL the is a second cache, called TableInfoCache.

supressing the MetaData-Caching:

IZConnection.SetUseMetadata(False);

Well i've commited one little patch R3436 \testing-7.2
suppressing TableInfoCache:

'NoTableInfoCache=True' 

to the PostgreSQL-ZURL.Properties. This suppresses caching table informations we added for the NativeResultSets.


All in one.. You wouldn't notice such memory consumtion if there is just one connection...

#125 Re: mORMot 1 » MVC/MVVM Web Applications with mORMot! » 2014-10-27 21:07:54

No never use CHAR fields IMHO. Better would be VARCHAR(x) fields in all cases. Else you would run either into trailing spaces issues or (this is what Zeos is doing) got a newly performance drop, because we do dec() length of string as long trailing spaces are used!

Instead of, i quickly commited a PGResultSet GetUTF8String override. Patch done R3435 \testing-7.2 (SVN).
This simply suppresse creating LOB buffers and directly return a UTF8String. Hope the Memory usage will decrease a bit?

#126 Re: mORMot 1 » MVC/MVVM Web Applications with mORMot! » 2014-10-27 20:09:50

Of course, they are threaded as CLOB, everything else would be wrong. Btw. your could also use VARCHAR with no length.

Hundrets MB of mem... hard to say. NOTE: Zeos internals do cache a loads of of Informations, instead of calling the Server again. Espezially for the slow PostgreSQL-server. This migth be one of Zeos performance advantages against FireDac. But this consumes Memory, of course.
Digging in.. the TZPGResultSet doesn't have a spezial GetUTF8String override yet. Currently i'm working on another refactoring: DO NOT DETERMINE all Columns-Information for !Reopened! reseultsets twice, just reset positions and handles instead. Slightly i've to many locale WC's. But having a look to the miising GetUTF8String override will be next.

May i ask if this example also uses ColumnsToJSON proc?

#127 Re: mORMot 1 » MVC/MVVM Web Applications with mORMot! » 2014-10-27 19:25:10

Arnaud,

does this sample use LOB's in any kind?

#128 Re: mORMot 1 » Zoes7.2 upgrade » 2014-10-22 08:30:04

Thanks Arnaud!

i was thinking about updating this link: http://blog.synopse.info/post/2013/11/0 … ing-MS-SQL
IFAIU is Oracle/FB not changed in the diagramm, or am i wrong?

Note: I'm one with red/green colors (eyes)issues. So reading/comparing the diagramms is ... hard/impossible for me, sorry. Is there a way you change the colors for the Access-layers?
Something like Blue = mMORot, Green = Zeos, Gray = x etc? That would help me very much.

I would like to use the link as reference, Arnaud.

Cheers, Michael

#129 Re: mORMot 1 » Zoes7.2 upgrade » 2014-10-21 21:51:50

@all

finally our official Beta-tag is done.
Download 7.2-Beta here: http://sourceforge.net/projects/zeoslib … p/download

@Arnaud

i would be happy if you could update your performance diagramms. smile


OpenSource ROCKS!

#130 Re: mORMot 1 » Firebird Batch DateTime Problem » 2014-10-08 18:49:12

Oh ok, thanks for sharing such knowledges. So let's say my proposal would hit some mirco-benchmarks with FastMM4.

Some weeks ago i did some research about FPC + FastMM4. I found some mailing lists of a user and Florian.
What i found out was: They did implement !some! parts which makes GetMem/ReallocMem comparable with FastMM4. But all other features are ignored AFAIRC.

Just a note, since mORMot seems to make the final steps for FPC cross-compiling..

Cheers, Michael

Edit, except you're checking against len+refcount for the result of the unquoted string, of course.

#131 Re: mORMot 1 » Firebird Batch DateTime Problem » 2014-10-08 10:44:34

Hi Arnaud,

don't want to bother you big_smile

Just a little tweak: Wouldn't it be faster for have a Iso8601ToDateTime function or overload which checks against quotes and returns the binary expected value? I mean instead of localize a new unquoted string and than call Iso8601ToDateTime? It's just a very minmal performance thing. What do you think?

#132 Re: mORMot 1 » Firebird Batch DateTime Problem » 2014-10-07 18:07:01

Arnaud,

may i ask .. is this issue Daniel reports a Zeos issue only? The patch you made seems to say YES whereas i think there is a common issue.
As Daniel describes there is a generic problem to convert TDateTime value if the values are quoted.

So what is wrong? Either Daniels JSON with quotes, mORMots conversion or simply my batch implementation for mORMot? Is this case handled for all providers and your own access units too?

Just to be clear... roll

#133 Re: mORMot 1 » Firebird Batch DateTime Problem » 2014-10-07 09:15:04

@AB,

seems to me like a parsing issue. Can't find something broken on ZDBC+FB. What about UnQuoting the strings by default?

@Daniel,

Did some small performance refactoring accordingly NULL determinations of FB+ArrayBindings -> update from SVN.

#135 Re: mORMot 1 » Problem with MySQL and CreateMissingTables » 2014-10-04 12:57:33

Note i did some MySQL reconnection refactoring on Zeos7.2:

Add

'MYSQL_OPT_CONNECT_TIMEOUT=x'
'MYSQL_OPT_RECONNECT=TRUE'

To the Connection/ZURL properties and the clientdll is doing the job. Don't know what happens if a connection is broken -> still missing a valid testcase ):

#136 Re: mORMot 1 » Wow! Full FPC support now??!! » 2014-10-04 12:48:15

Look to the FPC-Bugtracker ... they clicked snooze button sad
Except ab did a complex workaround. Maybe you push the FPC core (which mostly intents to make endless discussions) by writing objections for the severity state, which btw. i do NOT understand.

#137 Re: mORMot 1 » about UNICODE of DataSetToJSON in SynVirtualDataSet » 2014-09-24 22:44:16

Endeed there is an option: TZConnection.ConstrolsCodePage = cCP_UTF16. But using cCP_UTF8 should be best fit for mORMot afaik!
Note using cCP_UTF16 is not possible for current Zeos + D7/D2005 -> ftWideString persits as enum but TField.AsWideString isn't supported and a TWideMemo-Field is missing on Delphi db.pas.

Hack without warranty:

you'll find {$IF defined(ZEOS_TEST_ONLY) and defined(TEST_ZFIELDS)} in ZAbstractRODataset.pas. So if you add these
I'm not 100% ready with current TZFields. But TZWideStringField should work as well for D7 too. Another issue is a WideMemo field -> not ready by my selves.


Have my problems to understand what exactly the propblems are. What is expected if mORMot does fill it's JSON contents for D7-D2007? I still start from the premisse UTF8?

#138 Re: mORMot 1 » Batch+POST+Zeos+Firebird » 2014-09-14 15:29:56

First of all i still doesn't know about you ORM, Arnaud.

Did some research for "select MAX(ID)" but i didn't found enough to judge if it is session safe or not.

If i understand you correctly

ab wrote:

Once again, please understand that "select max(id)" is just called once, then the ORM maintains its own thread-safe ID.

then do you execute the determination once and all threads and sessions to get the value from the RestServer, right?

TSQLRestStorageExternal.EngineLockedNextID: Integer;

seems to execute this determinations. If now all clients get the Next ID from server, all ID generation is in sync with all threads/sessions and you are able to ensure NO other additional client can produce a constraint violation.. Everything is fine and forget about my warning.
But IMHO can nobody ensure this will never happen. Ok you can simply add a comment to the documentations and say this is not a mORMotish problem but this is eval, i think.
Intital issue i see are manual written queries and or non mORMotish clients..

ab wrote:

Numbers are talking. smile

Of course, as i said i understand you point of view.

ab wrote:

So my initial proposal was to simply by-pass the ORM for insertion in such "shared" tables, and rely on manual SQL written as a service, sharing the same ID generator logic than any legacy code.
It would certainly cost less to write some manual SQL statements in a mORMot service, to fit the existing sequence generation behavior on the legacy code, than changing the legacy code to fit mORMot's way of using sequences...

Uff a simple code snippet? No idea how you wanna do that right now.

ab wrote:

What do you think?

Create a abstract class with !current! behavior like the IZSequence. Allways accessable and default. Initial idea: Let the User decide if ID generation should happen current way or the "safe" way -> performance and than it's no longer an issue you've to think about, Arnaud.

Then i would introduce:

IDGenerator := array[low(TSQLDBDefinition)..High(TSQLDBDefinition)] of TAbstractIDGen = (....);

If this is done just introduce the classes in code. So it's not a huge refactoring at beginning.

Next would be to create RDBM speciffic classes. I did read the comments of Roberto Schneiders and the linked thred. Where i'm 100% sure about:

"select gen_id(Generator_NAME, xxx)" is LOADS faster than "select MAX(ID) from xxx"

And i wouldn't be surepriced if this would hit the goals for other providers too.
Also could this simply do the Genarator/sequence creation in its own logic e.g. CreateMissingTables.

ab wrote:

And once legacy code does not need any more to insert its data with its own SQL, and switched to n-Tier design, we may use the existing ORM code.

as i said i don't know enough about your framework. It was just a hypothetical guess. But my experiences are: you may start from the premisse such session constraint violations happens. And you should take care how to resolve this.
Another little guess: What will current mORMot do IF such a bad scenario happens. AFAICS there is no callback which executes a reset of the ID and resets all clients, or is there a emergency callback available?

Arnaud, i wrote with Daniel. I must admit my english is a bit .... Sometimes i've problems to understand you.

All in one and to be clear:
You fetch the ID once.
All clients get the next id from the RestServer, right?

Well my guess might be right but not insight your ORM. Only if (worst case) "someone" external  does some inserts and you get no notification about. So i'm more quiet now (some thing like 75%) smile. Excuse me, i really didn't know enough about.

Michael

#139 Re: mORMot 1 » Batch+POST+Zeos+Firebird » 2014-09-13 19:45:46

Did some research for my sequence suggestion and to resolve a "on demand" session-safe ID generation

FireBird (simplest one):
http://www.firebirdfaq.org/faq243/

instead of calling "select Max(ID)" you could use in
1. Batch mode:

use "select gen_id(GENERATOR_NAME, YourBatchCount)-YourBatchCount;" 

2. Single insertiation:

use "select gen_id(GENERATOR_NAME, 1);"

PostgreSQL/Oracle are more complicated since you can't increment the sequence by hand.

great Oracle description: http://www.dbanotes.com/database-develo … sequences/
PostgreSQL: Just a !untested! idea with a SP:

CREATE OR REPLACE FUNCTION NextId(seqname varchar, iters bigint)
RETURNS BIGINT AS
BEGIN
  select NextVal(seqname) as result;
  if iters > 1 then
    SetVal(seqname, result+iters);
END;
LANGUAGE 'PLPGSQL';

Don't know if this works for Oracle too.. Just an idea.
Edit: it would see http://www.gokhanatil.com/2011/01/how-t … ating.html
and for MSSQL too, see http://msdn.microsoft.com/de-de/library/ff878091.aspx

Now in all 3 cases you've got the first ID and you're sure no other session can get a id in range of returned ID + Itaration;
These Values can be used safely. This approach would be session safe, you can insert them by hand in your JSON contents, you won't run into a constraint issues and finally you won't have a leaking generator incrementing issue.

Oh and i found a quite nice syntax for MYSQL:

 INSERT INTO foo VALUES () ON DUPLICATE KEY UPDATE id = LAST_INSERT_ID (id +1);

But this wouldn't resolve the issue on you side. IMHO there is only the LAST_INSERT_ID call (SQL/API) which can be used session safe.


Disadvantages of my ideas: What about user permissions(altering a sequence)??

Cheers, Michael

#140 Re: mORMot 1 » Batch+POST+Zeos+Firebird » 2014-09-13 09:59:42

Thank you Arnaud. Writing fastcode is a permantal learning process for me too... So such "hard words" are welcome even if a first smile is missing... wink
And i did learn a loads from you too.

ab wrote:

And was tuned to work with our little mORMot.

Yes i did a loads to reach something like "perfect fit" for mORMot (which is an incredible not little framework IMHO). But i'm sure other ZDBC users will also benefit from latest refactoring. And we can also catch some more users to test current implementations!
Have one more idea which could be usefull for all ZDBC users: something like RowToText(ARowWriter: ITextWriter); OSLT. However feature adding did stop on 7.2 we'll go beta which means bugfixing only is allowed than. AND 7.3 goes into production.

Apart from this.. Arnaud finally i miss a little comment accordingly my objections i wrote before. Do i overlook something or do you plan some changes like (my ideas)

dependent to server create a sequence/genarator e.g. CreateMissingTables, and execute a "select gen_id()" to generate your id's instead.
EDIT: for FireBird you could also make a EXECUTE BLOCK stmt which fetches all ID's you need once. Something like this should be possible for PGSQL and Oracle too.
That would be multi-session save.
for MSSQL(in most areas a show-stopper ), MySQL no idea about best practice in batch mode...
Performance is pretty nice but not everything (like low level implementations smile ) I know this is hard to judge...

Just a final "Arnaud" stmt..

Second Edit:
Very simple (FB again): select gen_id(GENERATOR_NAME, YourBatchCount);
So you have last ID you can use ID := LastId-YourBatchCount+CurrentIteration. Multi-User/Session save too... And shouldn't take more round-trips like calling "select Max(ID)"

#141 Re: mORMot 1 » Batch+POST+Zeos+Firebird » 2014-09-13 08:39:10

@Daniel

Inital issue for my proposals: ALL ID's need to be "fetched" BEFORE or AFTER the insertion is done. This really means a performance loss for BATCH inserts as well. So i understand AB.

some links:
http://stackoverflow.com/questions/2944 … nserted-id
http://stackoverflow.com/questions/9477 … -statement
http://www.firebirdfaq.org/faq243/
...

All of them do point to a session "save" idea how to do that.. Let's stop that discussion. I think Arnaud know his code better then me..

#142 Re: mORMot 1 » Batch+POST+Zeos+Firebird » 2014-09-13 07:37:15

I didn't want to bother here. Simply thought Arnaud should think about it..

daniel wrote:

The trigger is fine for Firebird, but what when I decide to change my DB to SQLite?

MySQL: supports a mysql_insert_id call.
SQLite: supports a sqlite_last_insert_rowid call which Arnaud allready uses.
Postgres supports some more: Sequences or SerialFields -> use a returning clause
FB/Interbase, Oracle, DB2 as suggested before use a returning clause
MSSQL 'SELECT @@IDENTITY' which could be a ordinal or a guid...

All in one if there is no API-call like MySQL or SQLite have this mostly means performance decrease... So i do understand Arnaud.

Edit: And as Arnaud already mentioned: check the code -> which i really didn't yet. So my objections might be a bit "paranoid" wink

#143 Re: mORMot 1 » Batch+POST+Zeos+Firebird » 2014-09-13 05:50:13

ab wrote:

So it is centralized on the mORMot ORM level, protected with all multi thread safety as possible, for best speed. Max ID is run only once. Please see our code before doing wrong guess.

I'm not trying to teach you. It might be a wrong guess. Thought i'll point you to such "possible issues" in your current state.

ab wrote:

We have no time nor passion to recreate a hibernate complex system.

Of course! And it's not really required to do that. Example of Daniel again: He did implement a trigger how's doing the ID job. So my idea was to let the user decide if mORMot generates the values for primary keys or the DB is doing that. Than just work with a "RETURNING" clause for example. So you can update your JSON contents after insertations is done. AGAIN just some personal ideas. It's up to you to decide the best practice for your framework and i'm starting from the premisse you know what your're doing.

#144 Re: mORMot 1 » Zeos+Batch issue under 64bit » 2014-09-12 21:25:09

ab wrote:

If that is not low-level implementation, why not just one function (taking the pointer as input?), without inlining the complex expression (including the +1 for FPC) in every place of the code?

True. But only persits 3x in SetDataArray(). The String-length things are different from that. As you've pointed me in the past: PChar(aString) calls the RTL (since FPC2.7 too) so a check if Pointer(aString)=nil the Result := myEmptyStringPChar else Result := Pointer(aString). So it's not only the missing inline D7 function Length() which was reason for this kind of code...

Edit: simplification of LowLevel code is done R3304 \testing-7.2 (SVN)

#145 Re: mORMot 1 » Batch+POST+Zeos+Firebird » 2014-09-12 21:12:04

ab wrote:

It did, but it should have been fixed now.

What i can see is you fixed a little double constraint viaolation. What i mean is do you really generate the ID's this way? Or is it just a expression of Daniel?

If so -> Threads/Transactions/Multiuser-insertiations --> new constraint issues.. Thought using Max(ID) could called be 100 threads+connection @same time(or differnt but as long the transaction aren't commited the results are always the same(tiReadCommited f.e.)) so all of them are trying to insert a row with same starting to X ID's. My suggestion would be stop doing that. Could a user flag a field to let mORMot know such ID's are auto-generated?

Possible scenario:
Daniel nicely did add a BeforeInsert-Trigger which calls a sequence/genarator "if id_fiel = null then select gen_id() into id_field" (OSLT). However AFAICS does the trigger never do his job and the generator never increases it's value (which is fixable). Now another app attaches and inserts Daniels "Kontoauszüge" and left the ID field as NULL. Bang the trigger cames to shove and we'll have next constraint violation.

Should i go on with such bad scenarios? IMHO should the be a flag to exclude mORMotish generated values and use RDBM solutions instead. A generator/sequence (supported by Oracle, PostgreSQL, FB/Interbase, DB2) is a nice multiuser-save idea to prevent such cases. Each provider has it's own solutions. SQLite has its LastRowID, MySQL too, So a common way is hard to implement. But call a max(ID) usually is safe for one user and one transaction only.

#146 Re: mORMot 1 » Batch+POST+Zeos+Firebird » 2014-09-12 19:37:35

@daniel

the Exception should be fixed now for 64Bit too. Please test it.

@ab

Hope we got it, since my first idea was the bottlenek.

daniel wrote:

A little "error":

There must be a call of "select max(id) from table" twice.

Does the ID generation really happen this way?

#147 Re: mORMot 1 » Zeos+Batch issue under 64bit » 2014-09-12 19:27:54

public:

ab wrote:

Hello Michael

What do you think of http://synopse.info/forum/viewtopic.php … 461#p12461 ?

EgonHugeist wrote:

Hi Arnaud,

Writing from Smartphone now.. So i can't login on your board. It seems to me my Length determination for the DynArrays doesn't fit.
Somewhere in
ZDbcStatement.pas procedure BindArray();

Two possible issues:
1. The SizeOf the Length-Integer did increase to a Int64 an i read in second wrong bitmask.
2. There is another field i don't know about on Position where i read the value.

Now you're the DynArray hero, where is the position of DynArray-Length() located and how is this integer type defined?

IIRC do i read the length by doing something like this:

FInitalArray?Size? := PLengthInt(NativeUInt(Data)-LengthIntOffset)^;
These types are defined in ZCompatibility.pas. Not a problem to add a new type and offset for DynArrays too.

A advice would be welcome and you can have your patch in 3 hours if i'm back on computer.

Btw. All trunk merges synopse need are done!

Michael

.....

daniel wrote:

@EgonHugeist
Perhaps you can help us?

done: R3303 /testing-7.2 should resolve this problem. Sorry have no 64Bit Delphi to play with by my selves...
Sorry Arnaud friends did visit us so now it are 10 hours sad

ab wrote:

All those low-level access to the dynamic array are IMHO a wrong optimization, which leads to potential GPF issues.
A simple function or method (like in our TDynArray wrapper) is always better, and less error prone.
And with newer versions of Delphi or FPC, declaring them as "inline" is as fast as manual writing.

Than you don't understand my intention for the code in SetDataArry/SetNullArray completely wrong. That's NO low level optimization, Arnaud. We don't have a DynArray helper class like you need for your ORM. On this place i'm just checking the incomming lengths of the arrays to avod overflows later on processing the data! All i have is a POINTER, NO PTypeInfo(where the FPC did bother me on debugging again). So the simplest and minimal code todo that was this idea!

AFAICS do you use such low-level stuff too. DynArray -> FPC returns allways HIGH() not Length for this address. Check this on you side too. 
String-Length determination seems to differ too. Delphi uses a LongInt as RefCount & Length for 32&64Bit, FPC uses the SizeInt instead. The reason why i introduced the PLengthInt-thing.  Check this too for your framework, just a hint..

Cheers, Michael

#148 Re: mORMot 1 » ZEOS + Firebird + Update-Problem » 2014-09-02 20:04:52

ab wrote:

What are your thoughts about how to implement DB re-connection?

My "naive" proposals is to identify (per DB engine) the error codes corresponding to connection errors, then re-create the connection and the statement when these kind of errors are found.

exactly this is suppressed in our FB implementation, by a dev-member "AVZ"(which is a FB "guru"). Check ZDbcInterbaseUtils.pas -> PrepareStatement. I don't know whay this is done...

ab wrote:

We would benefit of an explicit "connection lost" error flag from ZDBC.

I've just added some error codes to the ticket details.
You may use it as reference.

I'll check your suggestion. Personaly i was thinking about registering a "TProcedure() of objet" as a callback routine if a connection lost happens. Flags are various and need to be handled from caller level again. So we need either a common flag or a callback function. (i would prefere this because each ZDBC interface could be closed and nil the handles silently). 

ab wrote:

If we have those at ZDBC level, I may be able to easily implement re-connection at mORMot level.
It may be a first step for you to fully implement reconnection for ZDBC 7.3.

might be a good idea!
But there must be done much more than trapping this error flags. What should really happen if a "Connection lost" happens? Best case would be reconnect with same handle which would catch such dead-lock situations too. Might be possible to implement(even if i don't think this is possible) need to check the API's. If this is not possible.. we need a shutdown or a admin who kills the unused connections than.

BTW. Ping is supported by IZConnection, Arnaud.

ab wrote:

My guess is like your statements. There must be always an open connection to Fb to the special field/row. When a client tries to update this field/row after a while, the open connection blocks the new update. Perhaps there is a cache on client-fb-connection keeping the connection open?

Possible if prepared non commited stmt-handle blocks the transaction of another connection. Thus i don't think this is the case. Our FB implmentation seems to be stable even if i changed a lot for better performance. The SQLite statement thing you did point me was another thing. Before the performance upgrades did happen, we had a complete different (strange) behavior for this plain. So after my changes we did return to a true alpha state. Thanks to synopse we did resolve these issues too.

#149 Re: mORMot 1 » ZEOS + Firebird + Update-Problem » 2014-09-01 21:25:33

@AB

ab wrote:

I'm no FireBird expert - does the client disconnect the server after a timeout?

Me too. I was simply thinking about: Why could another transaction raise a deadlock if he just uses one client. Actually Zeos doesn't handle possible reconnect issues(planned on 7.3). It might be possible a broken connection did force a new connection handle (done by your thread-safe-frame???) and the old connections+transaction aren't closed. AFAIK your access implementation do miss this case too. Intital issue i have: i have no idea how to setup a testcase for such situations like a bad WLAN or HTTP request.
Multitreading might be the evel too, but i couldn't see this in the toppic thread.
Anyway let's wait for reply..
What i know: PostgreSQL f.e. has a idle timeout: see http://sourceforge.net/p/zeoslib/tickets/72/

#150 Re: mORMot 1 » ZEOS + Firebird + Update-Problem » 2014-09-01 18:07:12

Hi Daniel,

i don't know enough about mORMot to know how it works with transactions. Was there a broken connection before? Something to know why a deadlock occours?

Board footer

Powered by FluxBB