日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 前端技术 > javascript >内容正文

javascript

Spring 事务失效的 8 种场景!

發布時間:2025/3/11 javascript 37 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Spring 事务失效的 8 种场景! 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

在日常工作中,如果對Spring的事務管理功能使用不當,則會造成Spring事務不生效的問題。而針對Spring事務不生效的問題,也是在跳槽面試中被問的比較頻繁的一個問題。

點擊上方卡片關注我

今天,我們就一起梳理下有哪些場景會導致Spring事務生效。

Spring事務不生效總覽

簡單來說,Spring事務會在幾種特定的場景下失效,如下圖所示。


1.數據庫不支持事務

Spring事務生效的前提是所連接的數據庫要支持事務,如果底層的數據庫都不支持事務,則Spring的事務肯定會失效。例如,如果使用的數據庫為MySQL,并且選用了MyISAM存儲引擎,則Spring的事務就會失效。

2.事務方法未被Spring管理

如果事務方法所在的類沒有加載到Spring IOC容器中,也就是說,事務方法所在的類沒有被Spring管理,則Spring事務會失效,示例如下。

public?class?ProductService?{@Autowiredprivate?ProductDao?productDao;@Transactional(propagation?=?Propagation.REQUIRES_NEW)public?void?updateProductStockCountById(Integer?stockCount,?Long?id){productDao.updateProductStockCountById(stockCount,?id);} }

ProductService類上沒有標注@Service注解,Product的實例沒有加載到Spring IOC容器中,就會造成updateProductStockCountById()方法的事務在Spring中失效。

3.方法沒有被public修飾

如果事務所在的方法沒有被public修飾,此時Spring的事務會失效,例如,如下代碼所示。

@Service public?class?ProductService?{@Autowiredprivate?ProductDao?productDao;@Transactional(propagation?=?Propagation.REQUIRES_NEW)private?void?updateProductStockCountById(Integer?stockCount,?Long?id){productDao.updateProductStockCountById(stockCount,?id);} }

雖然ProductService上標注了@Service注解,同時updateProductStockCountById()方法上標注了@Transactional(propagation = Propagation.REQUIRES_NEW)注解。

但是,由于updateProductStockCountById()方法為內部的私有方法(使用private修飾),那么此時updateProductStockCountById()方法的事務在Spring中會失效。

4.同一類中方法調用

如果同一個類中的兩個方法分別為A和B,方法A上沒有添加事務注解,方法B上添加了 @Transactional事務注解,方法A調用方法B,則方法B的事務會失效。例如,如下代碼所示。

@Service public?class?OrderService?{@Autowiredprivate?OrderDao?orderDao;@Autowiredprivate?ProductDao?productDao;public?void?submitOrder(){//生成訂單Order?order?=?new?Order();long?number?=?Math.abs(new?Random().nextInt(500));order.setId(number);order.setOrderNo("order_"?+?number);orderDao.saveOrder(order);//減庫存this.updateProductStockCountById(1,?1L);}@Transactional(propagation?=?Propagation.REQUIRES_NEW)public?void?updateProductStockCountById(Integer?stockCount,?Long?id){productDao.updateProductStockCountById(stockCount,?id);} }

submitOrder()方法和updateProductStockCountById()方法都在OrderService類中,submitOrder()方法上沒有標注事務注解,updateProductStockCountById()方法上標注了事務注解,submitOrder()方法調用了updateProductStockCountById()方法,此時,updateProductStockCountById()方法的事務在Spring中會失效。

5.未配置事務管理器

如果在項目中沒有配置Spring的事務管理器,即使使用了Spring的事務管理功能,Spring的事務也不會生效。

例如,沒有在項目的配置類中配置如下代碼。

@Bean public?PlatformTransactionManager?transactionManager(DataSource?dataSource)?{return?new?DataSourceTransactionManager(dataSource); }

此時,Spring的事務就會失效。

6.方法的事務傳播類型不支持事務

如果內部方法的事務傳播類型為不支持事務的傳播類型,則內部方法的事務在Spring中會失效。

例如,如下代碼所示。

@Service public?class?OrderService?{@Autowiredprivate?OrderDao?orderDao;@Autowiredprivate?ProductDao?productDao;@Transactional(propagation?=?Propagation.REQUIRED)public?void?submitOrder(){//生成訂單Order?order?=?new?Order();long?number?=?Math.abs(new?Random().nextInt(500));order.setId(number);order.setOrderNo("order_"?+?number);orderDao.saveOrder(order);//減庫存this.updateProductStockCountById(1,?1L);}@Transactional(propagation?=?Propagation.NOT_SUPPORTED)public?void?updateProductStockCountById(Integer?stockCount,?Long?id){productDao.updateProductStockCountById(stockCount,?id);} }

由于updateProductStockCountById()方法的事務傳播類型為NOT_SUPPORTED,不支持事務,則updateProductStockCountById()方法的事務會在Spring中失效。

7.不正確的捕獲異常

不正確的捕獲異常也會導致Spring的事務失效,示例如下。

@Service public?class?OrderService?{@Autowiredprivate?OrderDao?orderDao;@Autowiredprivate?ProductDao?productDao;@Transactional(propagation?=?Propagation.REQUIRED)public?void?submitOrder(){//生成訂單Order?order?=?new?Order();long?number?=?Math.abs(new?Random().nextInt(500));order.setId(number);order.setOrderNo("order_"?+?number);orderDao.saveOrder(order);//減庫存this.updateProductStockCountById(1,?1L);}@Transactional(propagation?=?Propagation.REQUIRED)public?void?updateProductStockCountById(Integer?stockCount,?Long?id){try{productDao.updateProductStockCountById(stockCount,?id);int?i?=?1?/?0;}catch(Exception?e){logger.error("扣減庫存異常:",?e.getMesaage());}} }

updateProductStockCountById()方法中使用try-catch代碼塊捕獲了異常,即使updateProductStockCountById()方法內部會拋出異常,但也會被catch代碼塊捕獲到,此時updateProductStockCountById()方法的事務會提交而不會回滾,并且submitOrder()方法的事務會提交而不會回滾,這就造成了Spring事務的回滾失效問題。

8.錯誤的標注異常類型

如果在@Transactional注解中標注了錯誤的異常類型,則Spring事務的回滾會失效,示例如下。

@Transactional(propagation?=?Propagation.REQUIRED) public?void?updateProductStockCountById(Integer?stockCount,?Long?id){try{productDao.updateProductStockCountById(stockCount,?id);}catch(Exception?e){logger.error("扣減庫存異常:",?e.getMesaage());throw?new?Exception("扣減庫存異常");} }

在updateProductStockCountById()方法中捕獲了異常,并且在異常中拋出了Exception類型的異常,此時,updateProductStockCountById()方法事務的回滾會失效。

為何會失效呢?這是因為Spring中對于默認回滾的事務異常類型為RuntimeException,上述代碼拋出的是Exception異常。

默認情況下,Spring事務中無法捕獲到Exception異常,所以此時updateProductStockCountById()方法事務的回滾會失效。

此時可以手動指定updateProductStockCountById()方法標注的事務異常類型,如下所示。

@Transactional(propagation?=?Propagation.REQUIRED,rollbackFor?=?Exception.class)

這里,需要注意的是:Spring事務注解@Transactional中的rollbackFor屬性可以指定 Throwable 異常類及其子類。

好了,今天就到這兒吧,我們下期見~~

總結

以上是生活随笔為你收集整理的Spring 事务失效的 8 种场景!的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。