Hi again Dan,

And thanks so much for your patience !

Well, this is a neat solution indeed. The fact is, I've never used
transactions so I don't know what they cost. At the very moment, I am
beginning an implementation using JTA. To begin with, let's say that I'll
probably abandon this idea in favor to yours. But I'd just want to expose it
for the sake of completeness:

First off, I plan to use a centralized session management system, so I don't
have to be concerned by the http server providing the web interface, i.e.
there could be many http servers running servlets that access my
application. To do this, I have a Stateful Session Bean I call a
UserSession, which is accessed by the servlets via a Stateless Session Bean
I call a Gatekeeper. Gatekeeper has a static Thread with a static Hashtable
field which holds the current active sessions. The thread part is used to
periodically check the time-to-live fields of the UserSessions, and
decrement them appropriately (and, again, I don't know if this is really
needed). By the time I was waiting to an answer to my last question, I had
defined the following methods to the remote interface of UserSession:

    public int checkPinCode ( String pinCode ) throws RemoteException;
    public boolean checkPseudo ( String pseudo ) throws RemoteException;
    public boolean setPassword ( String password ) throws RemoteException;
    public void setAnnouncePrefs ( int flags ) throws RemoteException;
    public void setUserData ( String data ) throws RemoteException;
    public void finishRegistration () throws RemoteException;

As I stated in my question, checking the pinCode is the first thing I do. So
in UserSessionBean (the actual EJB), this is what I was doing:

    SessionContext context;
    UserTransaction ut;
    Connection con;

    public int checkPinCode ( String pinCode )
        throws RemoteException
    {
        // obtain user transaction interface
        ut = context.getUserTransaction();
        // start a transaction
        try {
            ut.begin();
        } catch ( javax.transaction.NotSupportedException e ) {
            throw new RemoteException ( "transaction not supported" );
        } catch ( javax.transaction.SystemException e ) {
            throw new RemoteException ( "transaction system exception " +
e );
        }
        try {
            makeConnection();
        } catch (Exception ex) {
            throw new RemoteException("Unable to connect to database. " +
ex.getMessage());
        }

        try {
            // do the actual mess with the database...
            con.close ();
        } catch ( Exception ex ) {
            System.out.println ( "could not check pinCode: " + ex );
            throw new RemoteException ( "checkPinCode: " + ex.getMessage
() );
        }
        return 0;
    }

Of course, when everything finishes, I'd have to call ut.commit () (in the
finishRegistration () method) or rollback on time out, etc...

I'd be interested to read any comments on this, as I am at least going to
try out the darn thing, unless someone tells me to just not.

regards,

candide


> You're right, you have a problem.
>
> Just off the cuff, here's what I'd think about doing.
>
> I assume this is a web app? this makes it hurt worse.
>
> This is an awfully long transaction. You really don't want a real
> transaction open this long. Therefore, I'd use the HTTP Session to store
> up all the information I need, then make a call to a stateless session
> bean that does all of it in one transaction. I've made comments below on
> what I'd do differently.
>
>
> On Sat, 3 Mar 2001, fractals wrote:
>
> > Hi,
> >
> > This is a very simple question concerning transactions:
> >
> > I need to make a user-registration in multiple steps:
> >
> > 1. The user enters a pin code that corresponds to a certain amount of
money
> > he/she spent to get access to the application
> >     -> application checks the pin code, and marks a corresponding
pinCode
> > EJB that the pin code is now used (it cannot be used by another user at
the
> > same time)
> Mark the pinCode EJB 'reserved' at this point, so that we can tell this
> 'in process' stuff from actually used pin codes. Save the PIN in the
> session.
>
> >
> > 2. The user sets his/her pseudo
> >     -> application creates a new User EJB
> >     -> application validates pseudo
> Just save the pseudo in the HTTP Session. Probably build a bean that holds
> pseude, password, and preferences in the session. make that bean implement
> the session binding listener stuff, so it knows when it times out.
>
> >
> > 3. The user sets his/her password
> >     -> application validates password
> >     -> application sets the password on the User EJB
> Put the password in the same bean. Still no access to any User EJB
>
> >
> > 4. The user sets preferences and provides additional info
> >     -> application stores the data on the User EJB
> Put this in the same bean. No User EJB yet.
>
> >
> > 5. The user terminates and is prompted to log in
> >     -> everything's OK, the transaction can commit
> Call a session bean, passing it all the stuff we have in the session that
> creates the user, sets password and all prefs, etc, then marks the pinCode
> EJB 'used'. Tell the bean (the session thingy) that he's done then remove
> him from the session.
>
> >
> > At any point, the user can leave is/her chair/terminal so everything has
to
> > be rolled back after a given amount of time. This also means that the
> > temporary objects (rows), like the User EJB, have to be deleted.
> Since we haven't created anything, there isn't much to do. Remember that
> the bean in the session implemented the session binding listener
> stuff? That means that if he gets unbound before we tell him to complete
> (because the session timed out), he can clean up, which will consist of
> setting the pinCode EJB to 'unused' from 'reserved'
>
>
> What all this does is layers the user's logical unit of work over the top
> of the low-level transactions. One happy result is that we have a lot less
> transaction load hitting the EJB container, which will let it scale
> better. An unhappy result is that we're making our HTTP sessions bigger,
> which will effect the JSP/Servlet container's ability to scale. Make sure
> anthing you put into the HTTP Session is serializable so it can be swapped
> out. Consider saving session state in a temporary database (either
> directly from the JSP/servlet or via a tempuser EJB) to conserve memory.
>
>
> >
> > I'm not sure I've well understood the transaction mechanism. In
particular,
> > I don't understand when the transaction really begins and ends. As far
as I
> > got it, the transaction is a call-level mechanism: if a method is called
on
> > an object and that method calls another method of another object, the
whole
> > call chain forms the transaction. What I really need is a client to make
a
> > call to an object's method, then later, when my client makes a call to
> > another object's method, to be able, if anything goes wrong, to undo
what
> > was done before when the first object's method was called. I think the
> > following settings don't allow for such a thing:
> >
> > <ejb-jar>
> >     ...
> >     <assembly-descriptor>
> >     ...
> >     <container-transaction>
> >         <method>
> >             <ejb-name>User</ejb-name>
> >             <method-name>*</method-name>
> >         </method>
> >         <trans-attribute>Required</trans-attribute>
> >     </container-transaction>
> >     <container-transaction>
> >         <method>
> >             <ejb-name>PinCode</ejb-name>
> >             <method-name>markUsed</method-name>
> >         </method>
> >         <trans-attribute>Required</trans-attribute>
> >     </container-transaction>
> >     </assembly-descriptor>
> > </ejb-jar>
> >
> >
> > _______________________________________________
> > JBoss-user mailing list
> > [EMAIL PROTECTED]
> > http://lists.sourceforge.net/lists/listinfo/jboss-user
> >
>
> --
> Dan Christopherson (danch)
> nVisia Technical Architect (www.nvisia.com)
>
> Opinions expressed are mine and do not neccessarily reflect any
> position or opinion of nVISIA.
>
> --------------------------------------------------------------------------
-
> If you're a capitalist and you have the best goods and they're
> free, you don't have to proselytize, you just have to wait.
> -Eben Moglen
>
>
> _______________________________________________
> JBoss-user mailing list
> [EMAIL PROTECTED]
> http://lists.sourceforge.net/lists/listinfo/jboss-user
>


_______________________________________________
JBoss-user mailing list
[EMAIL PROTECTED]
http://lists.sourceforge.net/lists/listinfo/jboss-user

Reply via email to