This scenario using CMT is working:
Stateless session bean with CMT, one method annotated with
@TransactionAttribute(TransactionAttributeType.MANDATORY)
. Within this method, a record is written into a RDBMS using an XA data source and plain JDBC.The stand-alone client (separate JVM, command-line Java application) is getting a
UserTransaction
from the application server (by JNDI lookup), starts the transaction, and calls the EJB.If the client commits the
UserTransaction
, the record is written into the database.- If the client rollbacks the
UserTransaction
, the record is not written into the database. In the PostgreSql log files, one can see the prepared transaction with BEGIN, and COMMIT or ROLLBACK
If the client does not start a transaction before calling the EJB, a
javax.ejb.EJBTransactionRequiredException
is thrown (as expected,TransactionAttributeType.MANDATORY
).
Now I switch from CMT to BMT
Again, if the client does not start a transaction before calling the EJB, a
javax.ejb.EJBTransactionRequiredException
is thrown (as expected, TransactionAttributeType.MANDATORY).If I call
sessionContext.getUserTransaction().getStatus()
, it always reportsStatus.STATUS_NO_TRANSACTION
.The record is always written into the database, if the client calls
commit
orrollback
.In the PostgreSql log files, there are no prepared transactions, just plain insert commands.
The source of the EJB:
@Remote(DemoIfc.class)
@Stateless(name = "DemoBmt")
@TransactionManagement(TransactionManagementType.BEAN)
public class DemoBmt implements DemoIfc {
@Resource
private SessionContext sessionContext;
@TransactionAttribute(TransactionAttributeType.MANDATORY)
public String ping(final String s) throws SystemException {
try {
System.out.println("TX: status: "
+ this.sessionContext.getUserTransaction().getStatus());
} catch (Exception e) {
System.out.println("TX: status: " + e.getMessage());
}
try {
writeIntoDb();
if (s.startsWith("crash")) {
throw new SystemException("Simulated crash");
}
return s.toUpperCase();
} catch (NamingException e) {
throw new SystemException(e.getMessage());
} catch (SQLException e) {
throw new SystemException(e.getMessage());
}
}
}
The client's source:
final UserTransaction ut = (UserTransaction) initialContext
.lookup("UserTransaction");
try {
ut.begin();
System.out.println(demo.ping("crash: DemoBmt with UT"));
ut.commit();
} catch (Exception ex) {
System.out.println("Expected rollback");
ut.rollback();
}
I am using JBoss 6.0.0 final.
How can I properly propagate the client-side UserTransaction into the EJB with BMT?