Newsgroup: it.comp.java
Titolo: EJB & Transaction

Ciao a tutti,
ho qualche problema sull'utilizzo delle transazioni con le EJB,
probabilmente dovute ad alcune lacune.
Prima di entrare nello specifico, ciò che vorrei ottenere è questo:
dati alcuni session bean che eseguono operazioni elementari su db,
vorrei poter esporre un session bean (di facciata) che provveda alla
loro orchestrazione in modo transazionale...
Il Session Bean di facciata e così implementato:
@Stateless
public class EjbEnvelopeBean implements EjbEnvelopeLocal {
    @EJB
    private EjbInsertBLocal ejbInsertBBean;
    @EJB
    private EjbInsertALocal ejbInsertABean;
   @Resource
   private SessionContext sc;
   @TransactionAttribute(TransactionAttributeType.REQUIRES_NEW)
    public void invoke(String value) throws Exception {
        try{
            ejbInsertABean.insert(value);
            ejbInsertBBean.insert(value);
        //sc.getUserTransaction().commit();
        }
        catch(Exception ex ){
            ex.printStackTrace();
        }
    }
    // Add business logic below. (Right-click in editor and choose
    // "Insert Code > Add Business Method" or "Web Service > Add
Operation")
}
Come si vede dall'annotazione, il metodo invoke inizia una transazione
e chiama in successione due metodi di altrettanti Session Bean
I Session Bean sono implementati nel seguente modo:
@Stateless
public class EjbInsertABean implements EjbInsertALocal {
    @TransactionAttribute(TransactionAttributeType.SUPPORTS)
    public void insert(String value) throws RuntimeException{
        ConnectionManager cm = new ConnectionManager();
        try{
            Connection conn = cm.getConnection("ejbPool");
            StringBuilder insertSql = new StringBuilder("INSERT INTO
tabellaA (fieldA, fieldB) VALUES (?, ?)");
            PreparedStatement ps =
conn.prepareStatement(insertSql.toString());
            ps.setString(1, value);
            ps.setString(2, value);
            ps.executeUpdate();
        }
        catch(Exception ex){
            throw new RuntimeException();
        }
    }
}
@Stateless
public class EjbInsertBBean implements EjbInsertBLocal {
    @TransactionAttribute(TransactionAttributeType.SUPPORTS)
    public void insert(String value) throws RuntimeException {
        ConnectionManager cm = new ConnectionManager();
        try{
        Connection conn = cm.getConnection("ejbPool");
        StringBuilder insertSql = new StringBuilder("INSERT INTO
tabellaC (fieldA, fieldB) VALUES (?, ?)");
        PreparedStatement ps =
conn.prepareStatement(insertSql.toString());
        ps.setString(1, value);
        ps.setString(2, value);
        ps.executeUpdate();
        }
        catch(Exception ex){
            throw new RuntimeException();
        }
    }
}
Il secondo ejb (EjbInsertBBean) va in errore a causa del nome della
Tabella sbagliato nella INSERT.
Bene, essendo i metodi richiamati annotati con
TransactionAttributeType.SUPPORTS, dovrebbero condividere la
transazione iniziata dall'ejb chiamante.
Pur lanciando l'eccezione la insert dell'EjbInsertABean risulta alla
fine committata...
Cosa sbaglio?
Grazie infinite.


L'unica cosa che mi viene in mente è che il database non sia
transazionale. Di recente si è parlato di MyIsam vs InnoDB... non è
che stai usando appunto un database MySql su tabelle MyIsam? Comunque
quasi tutti i database possono essere configurati per avere un certo
tipo di transazionalità, compresa... nessuna! Ocio quindi :)
--
www.megadix.it


Ed era proprio questo! Il default di MySQL mi impostava le tabelle a
MyIsam... Grazie mille, ottima intuizione!!
Ancora grazie