Rollback mit CMT?

tobiaft

Mitglied
Hallo!

Ich habe folgendes Problem:

Ich habe Entity und Session Beans mit CMP und CMT.
Aus der Business-Methode eines Session-Beans rufe ich Methoden des selben Session-Beans und eines anderen Session-Beans auf.
Im Fehlerfall fange ich die Exceptions und setze sessionContext.setRollbackOnly(). Allerdings sind die Daten, die die gerufenen Methoden schreiben, schon committed. Diese sollen aber grade ge-rollback-t werden.

Liegt es an der Konfiguration, oder mache ich etwas falsch?

Beispielcode:
Code:
try{
  methode1();
  methode2();
} catch (Exception e){
  sessionContext.setRollbackOnly();
  throw e;
}

Danke...Tobias
 
N'Abend,

eigentlich sollte das schon funktionieren mit den Transaktionen. Hast du vielleicht für eine deiner Methoden ein anderes Transaktionsattribut als "Required" gesetzt?

gruß
THMD
 
Danke schon mal für die Antwort!

Ich habe jetzt im selben Session-Bean folgendes Tag hinzugefügt:
Code:
@ejb.transaction type="Required"

Die gesamte Deklaration sieht folgendermaßen aus:

Code:
/**
 * 
 * @ejb.bean name = "ClientViewOrder" type = "Stateful" display-name =
 *           "ClientViewOrder" description = "ClientViewOrder EJB" view-type =
 *           "remote" jndi-name = "ejb/ClientViewOrderHome"
 *           transaction-type="Container" 
 * @ejb.transaction type="Required"
 * @jboss.method-attributes pattern = "get*" read-only = "true"
 * @ejb.env-entry name="application_name" type="java.lang.String"
 *                value="@application.name@"
 */

In der anderen Session-Bean, in der ebenfalls eine Methode aufgerufen wird, stand bislang
Code:
@ejb.transaction type = "Supports"
.

Allerdings funktioniert der Rollback auch nicht, wenn ich hier ebenfalls "required" setze. Die gesamte Deklaration des aufgerufenen Session-Beans lautet:

Code:
/**
 * @ejb.bean name = "NewOrder" type = "Stateless" display-name = "NewOrder"
 *           description = "NewOrder EJB" view-type = "local" jndi-name =
 *           "ejb/NewOrderHome" local-jndi-name = "ejb/NewOrderBeanLocalHome"
 *           
 * @ejb.env-entry name="application_name" type="java.lang.String"
 *                value="@application.name@"
 * 
 * @ejb.transaction type = "Supports"
 * 
 */

Leider habe ich in der EJB-Dokumentation keine Infos erhalten, was 'Required' und 'Support' genau bedeutet.

Woran könnte es noch liegen, dass der Rollback nicht ausgeführt wird :confused:

Danke!
 
Required
Wenn die Methode ausserhalb einer Transaktion aufgerufen wird dann wird eine Transaktion neu aufgebaut.

Bei Supports im Gegensatz wird keine neue Transaktion erstellt wenn die Methode ausserhalb einer Transaktion aufgerufen wird.
 
Hallo,

deine XDoclet Tags sehen auf den ersten Blick OK aus. Ich nehme mal an er erzeugt dazu auch die richtigen Deskriptoren. Dann bleiben jetzt aufgrund des fehlenden eigentlichen Quellcodes der Methoden nur Vermutungen:

- Was meinst du mit "Daten werden geschrieben", benutzt du dafür Entity Beans?
- Wenn ja - haben die vielleicht noch eine andere Transaktionseinstellung?
- Ist der SessionContext auch richtig gesetzt?

Versuchs doch mal anstatt dem setRollbackOnly() testweise ein
Code:
throw new EJBException(e);
Er sollte dir jetzt eine Fehlermeldung bringen und gleichzeitig einen Rollback durchführen.

Wenn trotz Fehlermeldung die fehlerhaften Daten gespeichert werden, würde mich interessieren wie und wo du das Speichern durchführst. Das riecht dann nämlich dannach, das das Speichern außerhalb des Transaktionscontextes geschieht und dann ist es egal ob du einen Rollback machst oder nicht.

Gruß
THMD
 
Hm, alle Versuche schlagen bis jetzt fehl. Auch der Tipp mit der EJBException funktioniert leider nicht.

Noch mal etwas genauer: In einer Session-Bean (Code unten) wird eine Methode einer anderen Session-Bean drei Mal aufgerufen (methode1()). In methode1() werden Entity-Beans aufgerufen und somit Daten in die Datenbank gespeichert. Wahrscheinlich wird hier auch schon committed.

Code:
try{
  //1. Aufruf von methode1() in zweiter Session-Bean
  methode1();

  ...

  //2. Aufruf von methode1() in zweiter Session-Bean
  methode1();

  ...

  //3. Aufruf von methode1() in zweiter Session-Bean
  methode1();
} catch (Exception e){
  sessionContext.setRollbackOnly();
  throw e;
}

Nun kann es passieren, dass z.B. erst beim dritten Aufruf von methode1() eine Fehlermeldung kommt, und es müssten die 2 zuvor durchgeführten Transaktionen durch den Rollback idealerweise rückgängig gemacht werden. Daher der try-catch-Block um die 3 Aufrufe von methode1().
Die Entity-Beans haben teilweise eine 'Supports'-Transaktionseinstellung. Allerdings habe ich schon versucht, alle auf 'Supports' zu setzen, was nichts gebracht hat.

Kann schon sein, dass das Speichern außerhalb des Transaktionskontextes geschieht (eben so wie oben beschrieben), aber gibt es keine Möglichkeit mit dem Rollback alle bislang durchgeführten Speicherungen zu erfassen bzw. zu verhindern, dass die Daten schon committed werden?
 
Wieso hat die Methode die du aufrufst Support?
Denn dies verursacht das wenn die Methode ausserhalb einer Transaktion aufgerufen wird sie ohne Transaktionsunterstützung läuft.
Mandatory wirft dir eine Exception wenn sie ausserhalb einer Transaktion aufgerufen wird.
Definiere das mal, dann siehst du ja ob der Aufrufende auch wirklich transaktionell läuft.
Ansonsten bekommst du deine Exception.
 

Neue Beiträge

Zurück