Stateful session bean that retains transaction context across client calls

http://www.onjava.com/pub/a/onjava/2001/05/23/j2ee.html?page=4

Is this good example?

Does it worth implimentation?

In fact I want 3 methods:

1. To open entity for edit - transaction begins.

2. Save changes (Client Save button action) - transaction commit.

3. Cancel changes (Client Cancel button action) - transaction rollback.

Open transaction should prevent concurent access errors - I suspect to catch OptimisticLockException in method # 2.

[492 byte] By [Vitaliy_Kotova] at [2007-11-15]
# 1

Yes, stateful session beans with bean-managed transactions have always had the capability of

maintaining their transaction association across client invocations.

The concurrent access behavior is independent of this particular use-case.Most containers

throw an exception for any attempt to access a particular stateful session bean while it is

already processing an earlier request.

Regarding optimistic locking behavior, that is a function of exactly what API you are using to

access the database, how your tables are set up, and how the query is formed. I suggest

using the Java Persistence API, which has direct support for optimistic concurrency.

--ken

ksaksa at 2007-7-12 > top of java,Enterprise & Remote Computing,Enterprise Technologies...
# 2

I tried to use transaction in stateful session bean, but there is a problem. In first method I call begin(). getStatus() returns 0, but when I cal next method getStstus returns 6 (which means no transaction i suppose) and commit() throws exception with message null. It seems than transaction is commited after first method call. Here is my code:

@Stateful

@TransactionManagement(TransactionManagementType.BEAN)

public class ClientFacade implements ClientFacadeLocal, ClientFacadeRemote {

@EJB ClientsFacadeLocal mClient;

@EJB CladdressesFacadeLocal mCladdresses;

@EJB IdentdocsFacadeLocal mIdentdocs;

@Resource

UserTransaction mTransaction;

/** Creates a new instance of ClientFacade */

public ClientFacade() {

}

/**

* Transaction begin

*/

public void startTransaction() {

int stat = -1;

try {

stat = mTransaction.getStatus();

if (mTransaction.getStatus() != Status.STATUS_ACTIVE || mTransaction.getStatus() == Status.STATUS_NO_TRANSACTION) {

mTransaction.begin();

} else {

mTransaction.rollback();

mTransaction.begin();

}

} catch(Exception e)

{

this.rollbackTransaction();

Logging.LogException("ClientFacade", Level.SEVERE, "ClientFacade: Blad transakcji: begin. Status: " + stat

+ " ***************************************************************** "

+ e.getMessage());

}

}

/**

* Transaction rollback

*/

public void rollbackTransaction() {

try {

mTransaction.rollback();

} catch(Exception e)

{

Logging.LogException("ClientFacade", Level.SEVERE, "ClientFacade: Blad transakcji: rollback."

+ " ****************************************************************** "

+ e.getMessage());

}

}

/**

* Transaction commit

*/

public void commitTransaction() {

try {

mTransaction.commit();

} catch(Exception e)

{

Logging.LogException("ClientFacade", Level.SEVERE, "ClientFacade: Blad transakcji: commit."

+ " ******************************************************************** "

+ e.getMessage());

}

}

/**

* Create new client

*/

public Boolean addNewClient(Clients inClient)

{

Boolean result = false;

try

{

mClient.create(inClient);

this.commitTransaction();

result = true;

}

catch(Exception e)

{

this.rollbackTransaction();

}

return result;

}

}

I use EJB 3.0 on SJSAS 90 U1.

Thanks for your help.

gedeona at 2007-7-12 > top of java,Enterprise & Remote Computing,Enterprise Technologies...
# 3
Are you sure there was no prior exception that caused your code to call rollback?Take a lookin the server.log to see if there are any additional errors.Also, please post the stack trace of theexception that occurs when you call commit.
ksaksa at 2007-7-12 > top of java,Enterprise & Remote Computing,Enterprise Technologies...
# 4

I'm quite sure. There is nothing additional on server.log. I made additional tests with simplier stateful class:

@Stateful

public class ClientEdit implements ClientEditFacadeRemote {

private int counter;

/** Creates a new instance of ClientEdit */

public ClientEdit() {

}

public Integer getValue() {

return counter ;

}

public void addValue(Integer inValue) {

counter += inValue;

}

}

Each time when i call addValue() counter is 0. It behaves as a @stateless bean. Does it depend on SJSAS config?

gedeona at 2007-7-12 > top of java,Enterprise & Remote Computing,Enterprise Technologies...
# 5
How are you retrieving and accessing the SFSB ? Are you sure you're invoking thesame SFSB reference each time.Each injection or lookup of an SFSB using the EJB 3.0 viewcreates a new SFSB identity (instance). --ken
ksaksa at 2007-7-12 > top of java,Enterprise & Remote Computing,Enterprise Technologies...
# 6
That was the key to solution. I made JSP appliacation and each time i was creating new reference (in request bean). When I moved it to session bean all worked as I expected.Thanks for help
gedeona at 2007-7-12 > top of java,Enterprise & Remote Computing,Enterprise Technologies...