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.
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
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.
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?