{"id":183,"date":"2024-01-23T23:19:11","date_gmt":"2024-01-23T22:19:11","guid":{"rendered":"https:\/\/www.xn--javaeinfacherklrt-4qb.de\/?p=183"},"modified":"2024-01-24T23:20:08","modified_gmt":"2024-01-24T22:20:08","slug":"die-transactional-annotation-in-spring-jpa","status":"publish","type":"post","link":"https:\/\/www.xn--javaeinfacherklrt-4qb.de\/?p=183","title":{"rendered":"Die @Transactional-Annotation in Spring\/JPA"},"content":{"rendered":"\n<p>Die <code>@Transactional<\/code>-Annotation in einer Spring Boot-Anwendung spielt eine zentrale Rolle bei der Verwaltung von Transaktionen im Zusammenhang mit der Java Persistence API (JPA). Dieser Artikel wird sich ausf\u00fchrlich mit der Verwendung dieser Annotation in einer Spring Boot JPA-Anwendung befassen, insbesondere mit den verschiedenen Propagation-Varianten und Isolation-Levels, die sie bietet.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Einf\u00fchrung in @Transactional<\/h2>\n\n\n\n<p>Die <code>@Transactional<\/code>-Annotation wird in Spring verwendet, um Transaktionsverhalten f\u00fcr bestimmte Methoden zu definieren. In einer JPA-Anwendung kommt sie h\u00e4ufig zum Einsatz, um sicherzustellen, dass Operationen auf der Datenbank atomar, konsistent, isoliert und dauerhaft (ACID-Prinzipien) durchgef\u00fchrt werden.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Grundlegende Verwendung<\/h3>\n\n\n\n<p>Um die <code>@Transactional<\/code>-Annotation zu verwenden, platziert man sie einfach \u00fcber der Methode oder der Service-Klasse, die eine Transaktion ben\u00f6tigt. Hier ein einfaches Beispiel:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-1\" data-shcb-language-name=\"PHP\" data-shcb-language-slug=\"php\"><span><code class=\"hljs language-php\">@Service\n<span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-class\"><span class=\"hljs-keyword\">class<\/span> <span class=\"hljs-title\">MyService<\/span> <\/span>{\n\n    @Autowired\n    <span class=\"hljs-keyword\">private<\/span> MyRepository myRepository;\n\n    @Transactional\n    <span class=\"hljs-keyword\">public<\/span> void performTransaction() {\n        <span class=\"hljs-comment\">\/\/ Transaktionale Logik hier<\/span>\n        myRepository.save(entity);\n        <span class=\"hljs-comment\">\/\/ Weitere Logik...<\/span>\n    }\n}<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-1\"><span class=\"shcb-language__label\">Code-Sprache:<\/span> <span class=\"shcb-language__name\">PHP<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">php<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>In diesem Beispiel wird die <code>performTransaction<\/code>-Methode als Transaktion behandelt, und alle darin enthaltenen Operationen werden als Teil derselben Transaktion ausgef\u00fchrt.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Propagation-Varianten<\/h2>\n\n\n\n<p>Die Propagation-Variante legt fest, wie sich eine Transaktion verhalten soll, wenn sie auf eine bereits laufende Transaktion trifft oder wenn keine vorhanden ist. In Spring gibt es mehrere Propagation-Varianten, die durch das Attribut <code>propagation<\/code> der <code>@Transactional<\/code>-Annotation gesteuert werden.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">REQUIRED<\/h3>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-2\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript\">@Transactional(propagation = Propagation.REQUIRED)\npublic <span class=\"hljs-keyword\">void<\/span> requiredPropagation() {\n    <span class=\"hljs-comment\">\/\/ Transaktionale Logik hier<\/span>\n}<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-2\"><span class=\"shcb-language__label\">Code-Sprache:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>Die <code>REQUIRED<\/code>-Propagation gibt an, dass die Methode in einer vorhandenen Transaktion ausgef\u00fchrt werden sollte, oder eine neue Transaktion startet, falls keine vorhanden ist. Dies ist die Standard-Propagation und wird h\u00e4ufig verwendet.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">REQUIRES_NEW<\/h3>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-3\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript\">@Transactional(propagation = Propagation.REQUIRES_NEW)\npublic <span class=\"hljs-keyword\">void<\/span> requiresNewPropagation() {\n    <span class=\"hljs-comment\">\/\/ Transaktionale Logik hier<\/span>\n}<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-3\"><span class=\"shcb-language__label\">Code-Sprache:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>Die <code>REQUIRES_NEW<\/code>-Propagation gibt an, dass die Methode immer in einer neuen Transaktion ausgef\u00fchrt werden sollte. Wenn eine Transaktion bereits l\u00e4uft, wird sie pausiert und eine neue gestartet.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">NESTED<\/h3>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-4\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript\">@Transactional(propagation = Propagation.NESTED)\npublic <span class=\"hljs-keyword\">void<\/span> nestedPropagation() {\n    <span class=\"hljs-comment\">\/\/ Transaktionale Logik hier<\/span>\n}<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-4\"><span class=\"shcb-language__label\">Code-Sprache:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>Die <code>NESTED<\/code>-Propagation ist \u00e4hnlich wie <code>REQUIRED<\/code>, startet jedoch eine &#8222;verschachtelte&#8220; Transaktion innerhalb der aktuellen Transaktion. Wenn die \u00e4u\u00dfere Transaktion abgeschlossen wird, wird die innere Transaktion entweder committet oder zur\u00fcckgerollt, abh\u00e4ngig von ihrem eigenen Status.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">SUPPORTS<\/h3>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-5\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript\">@Transactional(propagation = Propagation.SUPPORTS)\npublic <span class=\"hljs-keyword\">void<\/span> supportsPropagation() {\n    <span class=\"hljs-comment\">\/\/ Transaktionale Logik hier<\/span>\n}<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-5\"><span class=\"shcb-language__label\">Code-Sprache:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>Die <code>SUPPORTS<\/code>-Propagation gibt an, dass die Methode in einer vorhandenen Transaktion ausgef\u00fchrt werden sollte, aber keine neue gestartet werden sollte, wenn keine vorhanden ist.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">NOT_SUPPORTED<\/h3>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-6\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript\">@Transactional(propagation = Propagation.NOT_SUPPORTED)\npublic <span class=\"hljs-keyword\">void<\/span> notSupportedPropagation() {\n    <span class=\"hljs-comment\">\/\/ Transaktionale Logik hier<\/span>\n}<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-6\"><span class=\"shcb-language__label\">Code-Sprache:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>Die <code>NOT_SUPPORTED<\/code>-Propagation gibt an, dass die Methode au\u00dferhalb einer Transaktion ausgef\u00fchrt werden sollte. Falls eine Transaktion bereits vorhanden ist, wird sie vor\u00fcbergehend pausiert.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">NEVER<\/h3>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-7\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript\">@Transactional(propagation = Propagation.NEVER)\npublic <span class=\"hljs-keyword\">void<\/span> neverPropagation() {\n    <span class=\"hljs-comment\">\/\/ Transaktionale Logik hier<\/span>\n}<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-7\"><span class=\"shcb-language__label\">Code-Sprache:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>Die <code>NEVER<\/code>-Propagation gibt an, dass die Methode au\u00dferhalb einer Transaktion ausgef\u00fchrt werden sollte. Wenn eine Transaktion bereits l\u00e4uft, wird eine Ausnahme ausgel\u00f6st.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Isolation-Levels<\/h2>\n\n\n\n<p>Das Isolation-Level einer Transaktion gibt an, wie die Transaktionsergebnisse in Bezug auf andere gleichzeitige Transaktionen behandelt werden. Spring unterst\u00fctzt verschiedene Isolation-Levels, die mithilfe des Attributs <code>isolation<\/code> der <code>@Transactional<\/code>-Annotation festgelegt werden k\u00f6nnen.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">DEFAULT<\/h3>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-8\" data-shcb-language-name=\"PHP\" data-shcb-language-slug=\"php\"><span><code class=\"hljs language-php\">@Transactional(isolation = Isolation.<span class=\"hljs-keyword\">DEFAULT<\/span>)\n<span class=\"hljs-keyword\">public<\/span> void defaultIsolation() {\n    <span class=\"hljs-comment\">\/\/ Transaktionale Logik hier<\/span>\n}<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-8\"><span class=\"shcb-language__label\">Code-Sprache:<\/span> <span class=\"shcb-language__name\">PHP<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">php<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>Das <code>DEFAULT<\/code>-Isolation-Level verwendet den Standard-Isolationsgrad der zugrunde liegenden Datenbank. Dies ist oft <code>READ_COMMITTED<\/code>, was bedeutet, dass eine Transaktion nur auf bereits committete Daten anderer Transaktionen zugreifen kann.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">READ_UNCOMMITTED<\/h3>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-9\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript\">@Transactional(isolation = Isolation.READ_UNCOMMITTED)\npublic <span class=\"hljs-keyword\">void<\/span> readUncommittedIsolation() {\n    <span class=\"hljs-comment\">\/\/ Transaktionale Logik hier<\/span>\n}<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-9\"><span class=\"shcb-language__label\">Code-Sprache:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>Das <code>READ_UNCOMMITTED<\/code>-Isolation-Level erlaubt einer Transaktion, auf noch nicht committete \u00c4nderungen anderer Transaktionen zuzugreifen. Dies birgt jedoch das Risiko von sogenannten &#8222;Dirty Reads&#8220;.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">READ_COMMITTED<\/h3>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-10\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript\">@Transactional(isolation = Isolation.READ_COMMITTED)\npublic <span class=\"hljs-keyword\">void<\/span> readCommittedIsolation() {\n    <span class=\"hljs-comment\">\/\/ Transaktionale Logik hier<\/span>\n}<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-10\"><span class=\"shcb-language__label\">Code-Sprache:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>Das <code>READ_COMMITTED<\/code>-Isolation-Level erm\u00f6glicht einer Transaktion nur den Zugriff auf bereits committete Daten anderer Transaktionen. Dies minimiert das Risiko von &#8222;Dirty Reads&#8220;.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">REPEATABLE_READ<\/h3>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-11\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript\">@Transactional(isolation = Isolation.REPEATABLE_READ)\npublic <span class=\"hljs-keyword\">void<\/span> repeatableReadIsolation() {\n    <span class=\"hljs-comment\">\/\/ Transaktionale Logik hier<\/span>\n}<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-11\"><span class=\"shcb-language__label\">Code-Sprache:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>Das <code>REPEATABLE_READ<\/code>-Isolation-Level stellt sicher, dass eine Transaktion auf dieselben Daten in derselben Reihenfolge zugreifen kann, unabh\u00e4ngig davon, ob andere Transaktionen in der Zwischenzeit \u00c4nderungen committen.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">SERIALIZABLE<\/h3>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-12\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript\">@Transactional(isolation = Isolation.SERIALIZABLE)\npublic <span class=\"hljs-keyword\">void<\/span> serializableIsolation() {\n    <span class=\"hljs-comment\">\/\/ Transaktionale Logik hier<\/span>\n}<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-12\"><span class=\"shcb-language__label\">Code-Sprache:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>Das <code>SERIALIZABLE<\/code>-Isolation-Level ist das strengste Level, bei dem alle Transaktionen so abgewickelt werden, als ob sie nacheinander ausgef\u00fchrt w\u00fcrden. Dies minimiert das Risiko von &#8222;Dirty Reads&#8220;, &#8222;Non-Repeatable Reads&#8220; und &#8222;Phantom Reads&#8220;.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Schlussfolgerung<\/h2>\n\n\n\n<p>In diesem Artikel haben wir die <code>@Transactional<\/code>-Annotation in einer Spring Boot JPA-Anwendung eingehend betrachtet. Wir haben die verschiedenen Propagation-Varianten und Isolation-Levels erkl\u00e4rt, die diese Annotation bietet, und wie sie dazu beitragen, die Integrit\u00e4t und Konsistenz von Datenbanktransaktionen zu gew\u00e4hrleisten.<\/p>\n\n\n\n<p>Es ist wichtig, die richtigen Propagation-Varianten und Isolation-Levels basierend auf den Anforderungen der Anwendung zu w\u00e4hlen. Die sorgf\u00e4ltige Verwendung dieser Annotation erm\u00f6glicht eine pr\u00e4zise Steuerung des Transaktionsverhaltens und tr\u00e4gt dazu bei, dass Datenbankoperationen in einer Spring Boot JPA-Anwendung effizient und zuverl\u00e4ssig abgewickelt werden.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Die @Transactional-Annotation in einer Spring Boot-Anwendung spielt eine zentrale Rolle bei der Verwaltung von Transaktionen im Zusammenhang mit der Java Persistence API (JPA). Dieser Artikel wird sich ausf\u00fchrlich mit der Verwendung dieser Annotation in einer Spring Boot JPA-Anwendung befassen, insbesondere mit den verschiedenen Propagation-Varianten und Isolation-Levels, die sie bietet. Einf\u00fchrung in @Transactional Die @Transactional-Annotation wird [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[5],"tags":[],"class_list":["post-183","post","type-post","status-publish","format-standard","hentry","category-spring"],"_links":{"self":[{"href":"https:\/\/www.xn--javaeinfacherklrt-4qb.de\/index.php?rest_route=\/wp\/v2\/posts\/183","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.xn--javaeinfacherklrt-4qb.de\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.xn--javaeinfacherklrt-4qb.de\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.xn--javaeinfacherklrt-4qb.de\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.xn--javaeinfacherklrt-4qb.de\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=183"}],"version-history":[{"count":1,"href":"https:\/\/www.xn--javaeinfacherklrt-4qb.de\/index.php?rest_route=\/wp\/v2\/posts\/183\/revisions"}],"predecessor-version":[{"id":184,"href":"https:\/\/www.xn--javaeinfacherklrt-4qb.de\/index.php?rest_route=\/wp\/v2\/posts\/183\/revisions\/184"}],"wp:attachment":[{"href":"https:\/\/www.xn--javaeinfacherklrt-4qb.de\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=183"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.xn--javaeinfacherklrt-4qb.de\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=183"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.xn--javaeinfacherklrt-4qb.de\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=183"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}