uebung6
This commit is contained in:
@@ -0,0 +1,578 @@
|
||||
# Componentware – Transaktionen, Packaging, Architektur und Spring Boot
|
||||
|
||||
## Inhalt
|
||||
|
||||
**Teil 1: Transaktionen & Packaging**
|
||||
- Transaktionen: Einführung, CMT, BMT, Client Managed
|
||||
- Packaging
|
||||
- Architektur
|
||||
- Abschließendes Beispiel
|
||||
|
||||
**Teil 2: Spring Boot**
|
||||
- Überblick über Spring
|
||||
- Starter
|
||||
- Anlegen eines Spring-Boot Projekts
|
||||
- Spring Shell
|
||||
- Komponenten, CDI
|
||||
- Zugriff auf Datenbanken / Spring Data
|
||||
- Messaging
|
||||
- Spring Web MVC / RESTful Web Services
|
||||
- Transaktionen
|
||||
|
||||
---
|
||||
|
||||
## Einführung
|
||||
|
||||
- Eine der wichtigsten Aufgaben des Entwicklers von Enterprise Systemen stellt die Aufrechterhaltung der Systemkonsistenz dar.
|
||||
- Falls von einem Geschäftsprozess mehr als eine Aktion durchgeführt wird, muss sichergestellt sein, dass entweder alle Einzelschritte oder gar keiner der Schritte durchgeführt wird.
|
||||
- Beispiel: Bestellung → Bestand reduzieren + Spediteur benachrichtigen. Beide Schritte müssen zusammen ablaufen.
|
||||
- Das Jakarta Transactions API (JTA) stellt diverse Möglichkeiten der Transaktionsverwaltung bereit.
|
||||
|
||||
### Ablauf einer Transaktion
|
||||
|
||||
1. Vor der ersten Ausführung wird eine Transaktion eröffnet.
|
||||
2. Der Zustand vor dem Start wird zwischengespeichert.
|
||||
3. Falls ein Fehler auftritt, markiert der Server die Transaktion als fehlerhaft.
|
||||
4. Falls alle Aktionen fehlerfrei durchlaufen → **commit** (zwischengespeicherte Zustände werden gelöscht).
|
||||
5. Falls die Transaktion als ungültig markiert wurde → **rollback** (Zustand vor der Transaktion wird wiederhergestellt).
|
||||
|
||||
Der Transaktionskontext wird entlang der Aufrufkette propagiert (bei Lookups, Injections oder Proxy-Objekten).
|
||||
|
||||
### ACID-Prinzip
|
||||
|
||||
| Eigenschaft | Bedeutung |
|
||||
|-------------|-----------|
|
||||
| **Atomicity** | Alle Teilschritte oder keiner wird ausgeführt. |
|
||||
| **Consistency** | Nach der Ausführung ist der Datenbestand konsistent. |
|
||||
| **Isolation** | Mehrere Transaktionen beeinflussen sich nicht gegenseitig. |
|
||||
| **Durability** | Ergebnisse sind dauerhaft (überstehen z.B. Server-Neustart). |
|
||||
|
||||
### 2-Phase-Commit
|
||||
|
||||
Bei verteilten Systemen erfolgt die Transaktion per 2-Phase-Commit:
|
||||
1. **Phase 1**: Transaktionskoordinator veranlasst Ausführung bei allen beteiligten Systemen.
|
||||
2. **Phase 2**: Bei Erfolg → finales Commit; bei Fehler → Rollback.
|
||||
|
||||
### Transaktionsarten
|
||||
|
||||
- **CMT (Container Managed Transactions)**: Voreinstellung bei EJBs – der Container übernimmt die Steuerung.
|
||||
- **BMT (Bean Managed Transactions)**: Der Entwickler steuert die Transaktionen selbst.
|
||||
- **Client Managed Transactions**: Der Client startet die Transaktion.
|
||||
|
||||
---
|
||||
|
||||
## Container Managed Transactions (CMT)
|
||||
|
||||
- Annotierung der Klasse mit `@TransactionManagement(TransactionManagementType.CONTAINER)` (ist Voreinstellung).
|
||||
- Transaktionen starten beim Client-Aufruf einer Methode und enden i.d.R. mit der Methode.
|
||||
- JMS-Nachrichten oder Datenbankstatements werden erst am Ende der Transaktion versendet.
|
||||
|
||||
### Rollback-Auslöser
|
||||
|
||||
1. **System-Exception** (von `RuntimeException` oder `java.rmi.RemoteException` abgeleitet):
|
||||
- Wird vom Server in eine Application-Exception verpackt und an den Client geleitet.
|
||||
- Rollback kann verhindert werden mit `@ApplicationException` an der Exception-Klasse.
|
||||
- Nach einer System-Exception in einer Stateful/Stateless Session Bean wird die Bean zerstört.
|
||||
|
||||
2. **Application-Exception mit `@ApplicationException(rollback=true)`**:
|
||||
- Application-Exceptions sind checked Exceptions (von `Exception`, aber nicht von `RuntimeException` abgeleitet).
|
||||
- Werden direkt an den Client weitergeleitet (kein Verpacken).
|
||||
- Checked Exceptions führen standardmäßig **nicht** zum Rollback.
|
||||
|
||||
3. **Manuell**: `sessionContext.setRollbackOnly()` (SessionContext per `@Resource` injizieren).
|
||||
|
||||
---
|
||||
|
||||
## CMT – `@TransactionAttribute`
|
||||
|
||||
```java
|
||||
@TransactionAttribute(TransactionAttributeType.<VALUE>)
|
||||
```
|
||||
|
||||
| Wert | Bedeutung |
|
||||
|------|-----------|
|
||||
| **REQUIRED** | (Standard) Vorhandenen Kontext verwenden oder neuen anlegen. |
|
||||
| **REQUIRES_NEW** | Immer neuen Kontext anlegen; vorhandener wird pausiert. |
|
||||
| **MANDATORY** | Vorhandener Kontext erforderlich; sonst `TransactionRequiredException`. |
|
||||
| **SUPPORTS** | Kontext wird übernommen, wenn vorhanden; sonst ohne Transaktion. |
|
||||
| **NOT_SUPPORTED** | Keinen Kontext verwenden; vorhandener wird unterbrochen. |
|
||||
| **NEVER** | Keinen Kontext akzeptieren; bei vorhandenem Kontext → `EJBException`. |
|
||||
|
||||
> **Hinweis**: Bei Message Driven Beans sind nur `REQUIRED`, `REQUIRES_NEW` und `SUPPORTS` möglich.
|
||||
|
||||
### `this`-Aufrufproblem
|
||||
|
||||
Ruft eine EJB-Methode eine andere Methode der **gleichen Klasse** über `this` auf, registriert der Container diesen Aufruf nicht → das Transaktionsattribut der aufgerufenen Methode wird ignoriert.
|
||||
|
||||
**Lösung**: Aufruf über eine andere Bean (per `@EJB` injiziert) oder über `sessionContext.getBusinessObject(KlassenName.class)`.
|
||||
|
||||
---
|
||||
|
||||
## CMT – Container Callback Methoden (Session Synchronisierung)
|
||||
|
||||
Für Stateful Session Beans, die länger als eine Transaktion leben. Interface: `SessionSynchronization` (oder Annotationen):
|
||||
|
||||
| Methode / Annotation | Zeitpunkt |
|
||||
|----------------------|-----------|
|
||||
| `afterBegin()` / `@AfterBegin` | Nach Beginn der Transaktion |
|
||||
| `beforeCompletion()` / `@BeforeCompletion` | In Phase 1 des 2-Phase-Commits |
|
||||
| `afterCompletion(boolean commit)` / `@AfterCompletion` | In Phase 2 (`true` = commit, `false` = rollback) |
|
||||
|
||||
---
|
||||
|
||||
## Bean Managed Transactions (BMT)
|
||||
|
||||
```java
|
||||
@TransactionManagement(TransactionManagementType.BEAN)
|
||||
```
|
||||
|
||||
Zugriff auf `UserTransaction` über `sessionContext.getUserTransaction()`.
|
||||
|
||||
### UserTransaction-Methoden
|
||||
|
||||
| Methode | Beschreibung |
|
||||
|---------|-------------|
|
||||
| `begin()` | Startet eine neue Transaktion. BMT kann nicht an propagierten Transaktionen teilnehmen. |
|
||||
| `commit()` | Beendet und bestätigt die Transaktion. |
|
||||
| `rollback()` | Beendet und verwirft die Transaktion. |
|
||||
|
||||
> **Achtung**: In Stateful Session Beans können Transaktionen über mehrere Methoden geöffnet bleiben – Transaktion muss in jedem Fall beendet werden.
|
||||
|
||||
---
|
||||
|
||||
## Client Managed Transactions
|
||||
|
||||
```java
|
||||
InitialContext ctx = new InitialContext(..);
|
||||
UserTransaction tx = (UserTransaction) ctx.lookup("UserTransaction");
|
||||
```
|
||||
|
||||
Steuerung über dieselben Methoden wie bei BMT: `begin()`, `commit()`, `rollback()`.
|
||||
|
||||
> Der Jakarta EE Standard empfiehlt Serverherstellern, Client-Transaktionen zu unterstützen – es ist jedoch keine Pflicht.
|
||||
|
||||
---
|
||||
|
||||
## Packaging
|
||||
|
||||
| Archivtyp | Inhalt | Verwendung |
|
||||
|-----------|--------|------------|
|
||||
| `.jar` | EJB-Projekt | EJB Application Archive |
|
||||
| `.war` | Web-Projekt | Web Application Archive |
|
||||
| `.ear` | jar + war + Deployment-Deskriptor | Enterprise Archive |
|
||||
|
||||
### EAR mit IntelliJ erstellen
|
||||
|
||||
1. Projekt gemäß Anleitung anlegen (ejb- und war-Module im Temp-Ordner belassen).
|
||||
2. Unter Artifacts → „Java EE Application: Archive" erstellen:
|
||||
- Output Directory = WildFly Deploy-Verzeichnis
|
||||
- „Include in project build" anhaken
|
||||
- EJB- und WAR-Artifact per Drag & Drop hinzufügen
|
||||
|
||||
---
|
||||
|
||||
## Architektur
|
||||
|
||||
### Klassische 3-Schichten-Architektur
|
||||
|
||||
```
|
||||
Bedieneroberfläche → Fachkonzept → Datenhaltung
|
||||
```
|
||||
|
||||
Mit Web-Controller (MVC):
|
||||
```
|
||||
Bedieneroberfläche → Controller → Fachkonzept → Datenhaltung
|
||||
```
|
||||
|
||||
Mit Jakarta EE Middleware:
|
||||
```
|
||||
Bedieneroberfläche → Controller → Middleware (EJBs / DAOs) → Datenhaltung
|
||||
```
|
||||
|
||||
### Data Transfer Objects (DTOs)
|
||||
|
||||
- **Ohne DTOs**: Entities werden direkt zum Client transportiert.
|
||||
- **Mit DTOs**: Auf den Client angepasste Klassen → bessere Sicherheit und Performance.
|
||||
|
||||
### Monolithische Applikationen vs. Microservices
|
||||
|
||||
#### Monolithen
|
||||
| Vorteile | Nachteile |
|
||||
|----------|-----------|
|
||||
| Einfache Entwicklung, IDE-Unterstützung | Schwer verständlich bei großer Codebasis |
|
||||
| Einfaches Deployment (eine Datei) | Skalierung nur für das Gesamtsystem |
|
||||
| Einfache End-to-End-Tests | Hohe Compilezeit |
|
||||
| Leicht mit Load Balancer skalierbar | Lange Start- und Testzeiten |
|
||||
|
||||
#### Microservices
|
||||
| Vorteile | Nachteile |
|
||||
|----------|-----------|
|
||||
| Kleinere, besser verständliche Codebasis | Schwierige Trennungsfindung |
|
||||
| Einzeln deploybar und skalierbar | Netzwerkkomplexität |
|
||||
| Teams können autonom arbeiten | Übergreifende Transaktionen schwierig |
|
||||
| Verschiedene Technologien möglich | Höherer Administrationsaufwand |
|
||||
| Schnellere Tests pro Service | Manche Aufgaben je Service implementieren |
|
||||
|
||||
---
|
||||
|
||||
## Das Spring Boot Framework
|
||||
|
||||
### Überblick
|
||||
|
||||
- Spring ist ein Entwicklungsframework für Enterprise Applikationen auf Java-Basis (Alternative zu Jakarta EE).
|
||||
- Erste Version: 2004; seit 2009 durch VMware entwickelt.
|
||||
- **Spring Boot** (ab 2014): deutlich vereinfachte Konfiguration durch Autokonfiguration.
|
||||
- Projekte anlegen über [https://start.spring.io](https://start.spring.io) oder IntelliJ.
|
||||
|
||||
### Spring vs. Spring Boot
|
||||
|
||||
| Spring | Spring Boot |
|
||||
|--------|-------------|
|
||||
| Container muss selbst konfiguriert werden | Sinnvolle Voreinstellungen |
|
||||
| Kein embedded Server | Embedded Apache Tomcat |
|
||||
|
||||
### Typische Module
|
||||
|
||||
- **Spring Data** – Datenbankzugriff
|
||||
- **Spring Web** – Webapplikationen inkl. RESTful Web Services
|
||||
- **Spring Security** – Authentifizierung und Autorisierung
|
||||
- **Spring Messaging** – Messaging
|
||||
- **Spring Cloud** – Cloud-Technologien (AWS, Azure, ...)
|
||||
|
||||
### Starter
|
||||
|
||||
Ein Starter ist eine Maven-Dependency, die alle für eine Technologie notwendigen Libraries lädt und eine Autokonfiguration vornimmt.
|
||||
|
||||
---
|
||||
|
||||
## Anlegen eines Spring-Boot-Projekts
|
||||
|
||||
### Hauptklasse
|
||||
|
||||
```java
|
||||
@SpringBootApplication
|
||||
public class SpringDemoApplication {
|
||||
public static void main(String[] args) {
|
||||
SpringApplication.run(SpringDemoApplication.class, args);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Interaktive Anwendungen mit der Spring Shell
|
||||
|
||||
Starter:
|
||||
```xml
|
||||
<dependency>
|
||||
<groupId>org.springframework.shell</groupId>
|
||||
<artifactId>spring-shell-starter</artifactId>
|
||||
</dependency>
|
||||
```
|
||||
|
||||
Shell-Methode erstellen:
|
||||
```java
|
||||
@Component
|
||||
public class HelloWorld {
|
||||
@Command(description = "hello: Says Hello World!")
|
||||
public String hello() {
|
||||
return "Hello World!";
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Aufruf im Prompt (Methodenname in kebab-case):
|
||||
```
|
||||
$> hello
|
||||
Hello World!
|
||||
```
|
||||
|
||||
Mit Parameter:
|
||||
```java
|
||||
@Command(description="hello-to --name <name>: ...")
|
||||
public String helloTo(@Option(required = true) String name) {
|
||||
return "Hello " + name;
|
||||
}
|
||||
```
|
||||
```
|
||||
$> hello-to --name Petra
|
||||
Hello Petra
|
||||
```
|
||||
|
||||
> **Hinweis**: In neueren IntelliJ-Versionen muss die App über Maven gestartet werden (`./mvnw spring-boot:run`).
|
||||
|
||||
---
|
||||
|
||||
## Komponenten
|
||||
|
||||
- POJOs werden mit `@Component` zu Spring-managed Beans.
|
||||
- Müssen in einem Unterpaket der Klasse mit `@SpringBootApplication` liegen.
|
||||
|
||||
### Dependency Injection
|
||||
|
||||
```java
|
||||
@Autowired
|
||||
private SomeManagedBean bean; // Attribut-Injection
|
||||
```
|
||||
|
||||
Besser: **Konstruktor-Injection** (final-Attribute möglich, testbar ohne Spring-Kontext):
|
||||
```java
|
||||
@Autowired
|
||||
public HelloWorld(HelloWorldComponent helloWorldComponent) {
|
||||
this.helloWorldComponent = helloWorldComponent;
|
||||
}
|
||||
```
|
||||
|
||||
### Semantische Annotationen
|
||||
|
||||
| Annotation | Verwendung |
|
||||
|------------|-----------|
|
||||
| `@Component` | Allgemeine Spring-managed Bean |
|
||||
| `@Service` | Service-Klassen (Fachlogik) |
|
||||
| `@Repository` | Data Access Objects |
|
||||
| `@Controller` / `@RestController` | Web-Controller |
|
||||
|
||||
---
|
||||
|
||||
## CDI in Spring
|
||||
|
||||
- **Component Scanning**: Spring sucht nach `@Component`, `@Repository`, `@Service`, `@Controller` im Paket der Hauptklasse und Unterpaketen.
|
||||
- **`@Bean`**: Entspricht CDI-Producern – macht Werte aus Methoden injizierbar.
|
||||
|
||||
```java
|
||||
@Bean
|
||||
public String name() {
|
||||
return "Max Mustermann";
|
||||
}
|
||||
```
|
||||
|
||||
- **`@ComponentScan`**: Erweitert den Suchpfad.
|
||||
- **Interceptoren**: `@PostConstruct` etc. wie in Jakarta EE. Alternativ AOP.
|
||||
|
||||
---
|
||||
|
||||
## Zugriff auf Datenbanken
|
||||
|
||||
### Spring Data JPA
|
||||
|
||||
Starter:
|
||||
```xml
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-data-jpa</artifactId>
|
||||
</dependency>
|
||||
```
|
||||
|
||||
`application.properties`:
|
||||
```properties
|
||||
spring.datasource.url=jdbc:mysql://localhost:3306/dbname
|
||||
spring.datasource.username=<username>
|
||||
spring.datasource.password=<password>
|
||||
spring.jpa.hibernate.ddl-auto=create-drop
|
||||
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
|
||||
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQLDialect
|
||||
```
|
||||
|
||||
> In Spring laufen Methoden **nicht automatisch transaktional** → `@Transactional` an Methoden oder Klassen notwendig.
|
||||
|
||||
### SimpleJpaRepository
|
||||
|
||||
```java
|
||||
SimpleJpaRepository<Book, Long> repository = new SimpleJpaRepository<>(Book.class, em);
|
||||
List<Book> books = repository.findAll();
|
||||
```
|
||||
|
||||
### CrudRepository / ListCrudRepository / JpaRepository
|
||||
|
||||
```java
|
||||
public interface BookJpaRepository extends JpaRepository<Book, Long> {
|
||||
// Methoden werden automatisch generiert
|
||||
}
|
||||
```
|
||||
|
||||
Kein `@Autowired` nötig – Spring erkennt das Interface und erstellt automatisch eine Implementierung.
|
||||
|
||||
---
|
||||
|
||||
## Messaging
|
||||
|
||||
Starter (ActiveMQ):
|
||||
```xml
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-activemq</artifactId>
|
||||
</dependency>
|
||||
```
|
||||
|
||||
ActiveMQ als Docker Container starten:
|
||||
```bash
|
||||
docker run -d --name activemq -p 61616:61616 -p 8161:8161 rmohr/activemq
|
||||
```
|
||||
|
||||
`application.properties`:
|
||||
```properties
|
||||
spring.activemq.broker-url=tcp://localhost:61616
|
||||
spring.activemq.user=admin
|
||||
spring.activemq.password=admin
|
||||
app.queue.name=buch.queue
|
||||
spring.jms.pub-sub-domain=false
|
||||
```
|
||||
|
||||
Hauptklasse:
|
||||
```java
|
||||
@SpringBootApplication
|
||||
@EnableJms
|
||||
public class MyApp { ... }
|
||||
```
|
||||
|
||||
### Receiver
|
||||
|
||||
```java
|
||||
@Component
|
||||
public class MessageReceiver {
|
||||
@JmsListener(destination = "springQueue")
|
||||
public void receiveMessage(Book receivedBook, Message message) {
|
||||
// Verarbeitung
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Sender
|
||||
|
||||
```java
|
||||
JmsTemplate jmsTemplate = context.getBean(JmsTemplate.class);
|
||||
jmsTemplate.convertAndSend("queueName", new Book("Buch", 42.99));
|
||||
```
|
||||
|
||||
### MessageConverter (für benutzerdefinierte Typen via JSON/Jackson)
|
||||
|
||||
```java
|
||||
@Bean
|
||||
public MessageConverter jacksonJmsMessageConverter() {
|
||||
JacksonJsonMessageConverter converter = new JacksonJsonMessageConverter();
|
||||
converter.setTypeIdPropertyName("_type");
|
||||
Map<String, Class<?>> typeIdMappings = new HashMap<>();
|
||||
typeIdMappings.put("buch", Buch.class);
|
||||
converter.setTypeIdMappings(typeIdMappings);
|
||||
return converter;
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Spring Web MVC – RESTful Web Services
|
||||
|
||||
Starter:
|
||||
```xml
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-web</artifactId>
|
||||
</dependency>
|
||||
```
|
||||
|
||||
### Controller
|
||||
|
||||
```java
|
||||
@RestController
|
||||
@RequestMapping("/hello")
|
||||
public class HelloWebService {
|
||||
@GetMapping
|
||||
public String sayHello() {
|
||||
return "Hello from Web Service";
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Mapping-Annotationen
|
||||
|
||||
| Annotation | HTTP-Methode |
|
||||
|------------|-------------|
|
||||
| `@GetMapping` | GET |
|
||||
| `@PostMapping` | POST |
|
||||
| `@PutMapping` | PUT |
|
||||
| `@DeleteMapping` | DELETE |
|
||||
|
||||
### Parameter
|
||||
|
||||
**Query-Parameter**:
|
||||
```java
|
||||
@GetMapping("/to")
|
||||
public String sayHelloTo(@RequestParam(value = "name", defaultValue = "World") String name) {
|
||||
return "Hello to " + name;
|
||||
}
|
||||
// Aufruf: http://localhost:8080/hello/to?name=Peter
|
||||
```
|
||||
|
||||
**Path-Parameter**:
|
||||
```java
|
||||
@GetMapping("/to/{name}")
|
||||
public String sayHelloToParam(@PathVariable String name) {
|
||||
return "Hello to " + name;
|
||||
}
|
||||
```
|
||||
|
||||
### Rückgabe von Objekten
|
||||
|
||||
```java
|
||||
@GetMapping("/book/{id}")
|
||||
public ResponseEntity<?> getBookById(@PathVariable long id) {
|
||||
Book book = bookJpaRepository.getReferenceById(id);
|
||||
return ResponseEntity.ok(book); // automatisch via JSON
|
||||
}
|
||||
```
|
||||
|
||||
### Empfang von Objekten
|
||||
|
||||
```java
|
||||
@PostMapping(path = "/book")
|
||||
public ResponseEntity<?> saveBook(@RequestBody Book book) {
|
||||
Book b = bookJpaRepository.save(book);
|
||||
return ResponseEntity.ok(b);
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Transaktionen in Spring
|
||||
|
||||
### Deklarativ (`@Transactional`)
|
||||
|
||||
```java
|
||||
@Transactional
|
||||
public void doSomething() {
|
||||
// läuft in einem Transaktionskontext ab
|
||||
}
|
||||
```
|
||||
|
||||
- Bei `RuntimeException` → automatischer Rollback.
|
||||
- Konfigurierbar: `readOnly`, Isolation (`REQUIRED`, `REQUIRES_NEW`), welche Exceptions zum Rollback führen.
|
||||
- Neuer Thread erhält keinen propagierten Transaktionskontext.
|
||||
|
||||
### Programmgesteuert
|
||||
|
||||
```java
|
||||
@Service
|
||||
public class DoSomethingService {
|
||||
@Autowired
|
||||
private PlatformTransactionManager transactionManager;
|
||||
|
||||
public void doSomething() {
|
||||
TransactionDefinition definition = new DefaultTransactionDefinition();
|
||||
TransactionStatus status = transactionManager.getTransaction(definition);
|
||||
try {
|
||||
// ... Datenbankoperationen ...
|
||||
transactionManager.commit(status);
|
||||
} catch (Exception e) {
|
||||
transactionManager.rollback(status);
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
#### Kernklassen
|
||||
|
||||
| Klasse | Rolle |
|
||||
|--------|-------|
|
||||
| `PlatformTransactionManager` | Führt Transaktionen technisch aus (begin, commit, rollback) |
|
||||
| `TransactionDefinition` | Beschreibt Eigenschaften (Propagation, Timeout, ReadOnly, Name) |
|
||||
| `TransactionStatus` | Repräsentiert die laufende Transaktion (Status abfragbar) |
|
||||
Reference in New Issue
Block a user