François,
thank you for your kind explanation of how JOnAS works.
I think that JOnAS team has a hard job, sure, but makes it's live too easy by always
telling that of EJB1.1 spec JOnAS cannot
do better (maybe I am wrong but I think it is a good point for public discussion):
> The most important message in this mail could be
> summarized as follows: EJB application performance
> is not only the result of the EJB application server
> intrinsic performance, but also of the application
> modelisation and deployment. The application
> modelisation in term of components (session and entity beans),
> and for example the transactional attributes that you will
> specify at deployment may have a big impact on the performance
> of the application. Unfortunately, unless the EJB leverages
> the programmers from many "system" concerns (transactions,
> db access, ...), I think she/he should still be aware of "how it
> works" in order to develop an application that will provide
> acceptable performance. It should be interesting to study
> books specialised in EJB programming. Unfortunately, as
> EJB platform providers, we are not specialists in EJB application
> development ! In french we say "ce sont les cordonniers les
> plus mal chaussés" (it is the shoe-makers who wear the more
> destroyed shoes). We have only few time to develop some samples
> and demos. Thus I will give you below only some hints.
This is the old discussion of who is responsable - the framework developer or the
framework user. EJB was intended to keep
all that stuff away from the application developer, by shifting that job over to the
container implementor. Sure can I
improve my performance by doing changes in the application. But isn't that the wrong
way to solve these problems? And aren't
the tricks in the books not more than workaround of specification faults or not clever
enough containers? I do not say that
you made your job bad - not the least, JOnAS is a very fine product - but I think you
should not start with an intro like
"JOnAS is as best as it can per definitiion". Maybe there is improvement possible.
> 1) Performance and entity beans manipulation
>
> You said in your e-mail to Gérard that the two main problems
> are the following:
>
> a) the fact that "the transmission of a Collection/Enumeration
> with some 1000 entries over RMI" is very slow (about 40 sec).
> You propose to write "a new Collection implementation that
> uses RMI and does not transmit the whole data at
> one time, but works like java.sql.ResultSet (getting each row
> over the net only if needed)".
>
> I do not think that it is the RMI transmission which is long.
> Actually, Collections/Enumerations
> returned by finder methods contains references to the EJB
> objects and not the whole data ? So it should not be so big,
> and so slow ... and most of the time is spent building the EJB
> objects on the EJB server. However, 40s seems very long to
> me, I will try to find out some measurements we have done,
> but I do not remember such long response times for finder
> methods.
Well, I wrote many, many System.println's into the code that GenIC produced,
recompiled that and measured the time between
the printing of the lines. What I found was that creation of the objects is faster
than you think, and REALLY, no joke, the
jump back returning from the server is the the problem. Try it out with client and
server on the same machine and about 1000
rows of data. If DB Server chaches work well, you will see that problem (or is SQL
Anywhere fast as lightning and so I
have different behaviour?).
But maybe my tests where not objective enough. I will re-do that tests and post you
detailed measuring. Another point: It's
an boring discussion if Collection itself or the objects inside it need the long time
to be deliverd. My idea is to get one
object by the next. So in any case this would solve the problem.
> b) "The other point is that JOnAS does a RMI call every time
> the client application does a ...getXXX."
>
> This is a problem of EJB application conception. An EJB
> server cannot provide client side data caching, at least in
> a "standard" way. You will see in many EJB books and
> programming guides, that it is not recommended to
> manipulate entity beans directly from the client application.
I will not manipulate entity beans. Who told you? If I see EJB specs right, it's the
container implementor's choice in what
way he implements all the stuff around EJB 1.1. So, for EJB 1.1 does not permit to
cache the values, who else will do?
> This is because the data is cached in the EJB instance, on
> the server side, and the client can only manipulate a
> reference to this object. Thus for each access to the
> EJB, you will have a remote call (and eventually a database
> access, see point 2 below).
Yes, but where is written in EJB 1.1 that you may not cache on the client, too? An
entity bean is loaded once from the DBMS
(ejbLoad), and stored once (ejbSave). So between ejbLoad and ejbSave the container
implementor can do what s/he wants.
Inprise for example does writing the instance into a stream if memory is needed (!).
So why shouldn't it be save to cache the
value to suppress the RMI call? Or is written in EJB 1.1 that there HAS to be a call
EVERY time? Second, the value cannot
change between calls, because of transactional behaviour.
> Therefore what is recommended is to build session beans,
> that will aggregate operations on entity beans, and return
> the whole data needed by the client. You may also define
> methods on the entity beans that return a bunch of data
> instead of EJB references (as finder methods do).
But this does not solve the problem: Session beans also use RMI. It's not the LAN,
it's the RMI!
Returning a bunch of data is also only a workaround: It's neither object oriented
design, nor is it transparent to the
application developer. Nor improves it performance in every case: We have beans that
encapsulate LONG VARBINARY. What if I
only need the name or version fields, but not the (maybe 100MB large) content of such
a bean? Returning a bunch means to
return the LONG VARBINARY if I only need a SMALLINT...
> 2) Transactional behaviour and entity beans
>
> This is an explanation of the behaviour that you described
> in your last e-mail and that I recall below : you have an entity
> bean with the TX_REQUIRED attribute defined for each
> method, and your client does not start any transaction and does:
> myEntity.getX();
> myEntity.getY();
>
> and you can see on the server the "traces"
> myEntity.ejbLoad();
> myEntity.getX();
> myEntity.ejbStore(); // THAT IS NOT NEEDED YOU THINK
> myEntity.ejbLoad();
> myEntity.getY();
> myEntity.ejbStore();
>
> You say the ejbStore in the middle is not needed. You're right
> but having defined the TX_REQUIRED attribute (I think this
> is what you call "NeedsTransaction") on the bean
Yes, I mean TX_REQUIRED
> methods (getX and getY) and not starting a method in the client
> has the following effect:
> - the container will start a new transaction T1 just for executing
> getX, thus executing ejbLoad, and ejbStore (this last operation
> at the T1 commit time),
> - the container will start a new transaction T2 for executing getY,
> .....
Is this really a must of EJB 1.1 spec? I know of Inprise Application Server doing this
another way. If a client calls a
entity bean there (TX_REQUIRED), a "global" transaction is used. If it is not
existing, it's created. If it is there, it only
used (!). ALL calls now use this transaction. It is NOT closed between calls (this
would be TX_REQUIRES_NEW)! It is closed by
timeout. So, I would please you to tell me: Is it JOnAS specific that the transaction
is closed between calls, or is it
needed from the spec? All I read about TX_REQUIRED is, that a transaction is used, but
NOT that it had to be closed directly
after a call. I think that timeout solution of Inprise is quite OK for the EJB 1.1
spec, and it would solve the problem!
Sure, better solution would be to call this from inside an SB's TX_REQUIRES_NEW
method, but this clearly points out that you
can read EJB 1.1 spec THIS way O R THAT way...!
> So the ejbLoad and ejbStore you see are perfectly normal. This
> is a behaviour according to your transaction attributes. The way to
> execute getX and getY in the same transaction (and thus avoiding
> the "middle" ejbStore) is to start a transaction embedding the 2 calls
> from the client, OR to perform the two calls in a method of a session
> bean (that will have the TX_REQUIRES_NEW attribute), and to
> call this method from the client (which is related to the discussion
> above, 1-b).
> In the last version of JOnAS, you may also be able to avoid
> the "middle" ejbStore by using the TX_SUPPORTS or
> TX_NOT_SUPPORTED on your methods, and by not starting
> a transaction on the client. Thus your methods will execute outside
> any transaction.
But I WANT execution INSIDE a transaction.
Is it REALLY wanted EXPLICITELY in the EJB 1.1 spec, that in TX_REQUIRES (not _NEW) to
close between calls and NOT doing only
a timeout? So what Inprise Application Server 4 does has to be quite wrong (and they
should not be proud of their
performance).
For I do not have EJB 1.1 specs here, I would really please you to read this in detail
and with my interpretion in mind. Or
could you please send me EJB 1.1 specs? So I will read before I make new suggestions.
Thank you
Markus