שגיאת TransactionRequiredException

1. סקירה כללית

במדריך זה נבחן את הסיבה ל TransactionRequiredException שגיאה וכיצד לפתור אותה.

2. TransactionRequiredException

שגיאה זו מתרחשת בדרך כלל כאשר אנו מנסים לבצע פעולת מסד נתונים המשנה את מסד הנתונים ללא עסקה.

לדוגמא, ניסיון לעדכן רשומה ללא עסקה:

שאילתת עדכון Query = session.createQuery ("עדכן הודעה p SET p.title =? 1, p.body =? 2 WHERE p.id =? 3"); updateQuery.setParameter (1, כותרת); updateQuery.setParameter (2, גוף); updateQuery.setParameter (3, id); updateQuery.executeUpdate ();

יעלה חריג עם הודעה בשורות הבאות:

... javax.persistence.TransactionRequiredException: ביצוע שאילתת עדכון / מחיקה ב- org.hibernate.query.internal.AbstractProducedQuery.executeUpdate (AbstractProducedQuery.java:1586) ...

3. מתן עסקה

הפיתרון הברור הוא לעטוף כל פעולת שינוי מסד נתונים בעסקה:

Transaction txn = session.beginTransaction (); שאילתת עדכון Query = session.createQuery ("עדכן הודעה p SET p.title =? 1, p.body =? 2 WHERE p.id =? 3"); updateQuery.setParameter (1, כותרת); updateQuery.setParameter (2, גוף); updateQuery.setParameter (3, id); updateQuery.executeUpdate (); txn.commit ();

בקטע הקוד שלמעלה אנו יוזמים ומבצעים את העסקה באופן ידני. למרות ש בסביבת Spring Boot, אנו יכולים להשיג זאת באמצעות ה- @ Transactional ביאור.

4. תמיכה בעסקאות באביב

אם אנחנו רוצים שליטה דקה יותר נוכל להשתמש בשליטת האביב TransactionTemplate. מכיוון שזה מאפשר למתכנת להפעיל את ההתמדה של אובייקט מיד לפני שתמשיך בביצוע הקוד של שיטה.

לדוגמא, נניח שאנחנו רוצים לעדכן את הפוסט לפני שנשלח הודעת אימייל:

עדכון חלל ציבורי () {entityManager.createQuery ("UPDATE Post p SET p.title =? 2, p.body =? 3 WHERE p.id =? 1") // פרמטרים .executeUpdate (); שלח אימייל(); }

החלת ה- @ Transactional לשיטה לעיל עלול לגרום למשלוח הדוא"ל למרות חריג בתהליך העדכון. הסיבה לכך היא שהעסקה תבוצע רק כאשר השיטה תצא ועומדת לחזור למתקשר.

לכן, עדכון הפוסט בתוך א TransactionTemplate ימנע תרחיש זה מכיוון שהוא יבצע את הפעולה באופן מיידי:

עדכון חלל ציבורי () {transactionTemplate.execute (transactionStatus -> {entityManager.createQuery ("UPDATE Post p SET p.title =? 2, p.body =? 3 WHERE p.id =? 1") // פרמטרים. executeUpdate (); transactionStatus.flush (); return null;}); שלח אימייל(); }

5. מסקנה

לסיכום, בדרך כלל נוהג לעטוף פעולות מסד נתונים בעסקה. זה עוזר במניעת שחיתות נתונים. קוד המקור השלם זמין ב- Github.


$config[zx-auto] not found$config[zx-overlay] not found