@Transactional的使用


 

原文鏈接:https://blog.csdn.net/u013929527/article/details/102596243

 

1.Spring事務的原理
Spring 事務管理分為編碼式和聲明式的兩種方式。編程式事務指的是通過編碼方式實現事務;聲明式事務基於 AOP,將具體業務邏輯與事務處理解耦。聲明式事務管理使業務代碼邏輯不受污染, 因此在實際使用中聲明式事務用的比較多。聲明式事務有兩種方式,一種是在配置文件中做相關的事務規則聲明,另一種是基於@Transactional 注解的方式。
使用@Transactional的相比傳統的我們需要手動開啟事務,然后提交事務來說。它提供如下方便

  • 根據你的配置,設置是否自動開啟事務
  • 自動提交事務或者遇到異常自動回滾

聲明式事務(@Transactional)基本原理如下:

  1. 配置文件開啟注解驅動,在相關的類和方法上通過注解@Transactional標識。
  2. spring 在啟動的時候會去解析生成相關的bean,這時候會查看擁有相關注解的類和方法,並且為這些類和方法生成代理,並根據@Transaction的相關參數進行相關配置注入,這樣就在代理中為我們把相關的事務處理掉了(開啟正常提交事務,異常回滾事務)。
  3. 真正的數據庫層的事務提交和回滾是通過binlog或者redo log實現的。

 

 

 

2.@Transactional使用注意點
@Transactional注解只能在拋出RuntimeException或者Error時才會觸發事務的回滾,常見的非RuntimeException是不會觸發事務的回滾的。但是我們平時做業務處理時,需要捕獲異常,所以可以手動拋出RuntimeException異常或者添加rollbackFor = Exception.class(也可以指定相應異常)

  1. @Transactional注解只能在拋出RuntimeException或者Error時才會觸發事務的回滾,常見的非RuntimeException是不會觸發事務的回滾的。但是我們平時做業務處理時,需要捕獲異常,所以可以手動拋出RuntimeException異常或者添加rollbackFor = Exception.class(也可以指定相應異常)

    

 1 /*
 2  * 捕獲異常時,要想使事務生效,需要手動拋出RuntimeException異常或者添加rollbackFor = Exception.class
 3 */
 4 @Override
 5 @Transactional
 6 public Long addBook(Book book) {
 7     Long result = null;
 8     try {
 9         result = bookDao.addBook(book);
10         int i = 1/0;
11     } catch (Exception e) {
12         e.printStackTrace();
13         throw new RuntimeException();
14     }
15     return result;
16 }
17 
18 @Override
19 @Transactional(rollbackFor = Exception.class)
20 public Long addBook(Book book) {
21     Long result = null;
22     try {
23         result = bookDao.addBook(book);
24         int i = 1/0;
25     } catch (Exception e) {
26         e.printStackTrace();
27         throw e;
28     }
29     return result;
30 }

 

  2.只有public修飾的方法才會生效

  3.方法內自調用導致的事務不生效

 

以下幾種情況

 1 /*
 2 * 情況一:都有事務注解,異常在子方法出現,事務生效
 3 */
 4 @Override
 5 @Transactional
 6 public Long addBook(Book book) {
 7     Long result = add(book);
 8     return result;
 9 }
10 
11 @Transactional
12 public Long add(Book book){
13     Long result =  bookDao.addBook(book);
14     int i = 1/0;
15     return result;
16 }
17 
18 /*
19 * 情況二:都有事務注解,異常在主方法出現,事務生效
20 */
21 @Override
22 @Transactional
23 public Long addBook(Book book) {
24     Long result = add(book);
25     int i = 1/0;
26     return result;
27 }
28 
29 @Transactional
30 public Long add(Book book){
31     Long result =  bookDao.addBook(book);
32     return result;
33 }
34 
35 /*
36 * 情況三:只有主方法有事務注解,異常在子方法出現,事務生效
37 */
38 @Override
39 @Transactional
40 public Long addBook(Book book) {
41     Long result = add(book);
42     return result;
43 }
44 
45 public Long add(Book book){
46     Long result =  bookDao.addBook(book);
47     int i = 1/0;
48     return result;
49 }
50 
51 /*
52 * 情況四:只有主方法有事務注解,異常在主方法出現,事務生效
53 */
54 @Override
55 @Transactional
56 public Long addBook(Book book) {
57     Long result = add(book);
58     int i = 1/0;
59     return result;
60 }
61 
62 public Long add(Book book){
63     Long result =  bookDao.addBook(book);
64     return result;
65 }
66 
67 /*
68 * 情況五:只有子方法有事務注解,異常在子方法出現,事務不生效
69 */
70 @Override
71 public Long addBook(Book book) {
72     Long result = add(book);
73     return result;
74 }
75 
76 @Transactional
77 public Long add(Book book){
78     Long result =  bookDao.addBook(book);
79     int i = 1/0;
80     return result;
81 }

結論:當無事務方法調用有事務的方法時事務不會生效,而主方法有事務去調用其他方法,無論被調用的方法有無事務,且是否出現異常(有異常需要能夠拋出不被捕獲),都觸發事務。

 

自己寫代碼時的注解

1 @Transactional(rollbackFor = {Exception.class})
2     @Override
3     public void importData(InputStream inputStream) {
4         EasyExcel
5                 .read(inputStream, ExcelDictDTO.class,new ExcelDictDTOListener())
6                 .sheet()
7                 .doRead();
8         log.info("Excel導入成功");
9     }

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM