Spring事務是指在Spring框架中對于數據庫操作的一種支持,它通過對一組數據庫操作進行整體控制來保證數據的一致性和完整性。Spring事務可以保證在一組數據庫操作執行時,要么所有操作都執行成功,要么所有操作都回滾到之前的狀態,從而避免了數據不一致的情況。
Spring事務可以通過編程式事務和聲明式事務兩種方式來實現。編程式事務需要在代碼中手動控制事務的開始、提交和回滾等操作,而聲明式事務則是通過在配置文件中聲明事務的切入點和通知等信息來自動控制事務的行為。
Spring編程式事務需要在代碼中獲取事務管理器,并通過該事務管理器獲取事務對象,然后使用該事務對象來控制事務的開始、提交和回滾等操作。
publicvoidtransferMoney(AccountfromAccount,AccounttoAccount,doubleamount){TransactionStatusstatus=transactionManager.getTransaction(newDefaultTransactionDefinition());try{fromAccount.withdraw(amount);toAccount.deposit(amount);transactionManager.commit(status);}catch(Exceptione){transactionManager.rollback(status);}}
在上面的代碼中,首先通過transactionManager.getTransaction
方法獲取事務對象status
,然后在try
塊中執行轉賬操作,最后通過transactionManager.commit(status)
提交事務。如果在轉賬操作中發生了異常,則會通過transactionManager.rollback(status)
回滾事務。
編程式事務的優點是靈活性高,可以根據具體的業務需求來靈活控制事務的行為。不過缺點是代碼冗長,可讀性差,而且容易出現錯誤。
Spring聲明式事務需要在配置文件中聲明事務管理器、事務通知等元素,然后在需要使用事務的方法上添加事務切面的注解即可。
<beanid="transactionManager"class="org.springframework.jdbc.datasource.DataSourceTransactionManager"><propertyname="dataSource"ref="dataSource"/></bean><tx:adviceid="txAdvice"transaction-manager="transactionManager"><tx:attributes><tx:methodname="transferMoney"propagation="REQUIRED"/></tx:attributes></tx:advice><aop:config><aop:pointcutid="transferPointcut"expression="execution(*com.example.TransferService.transferMoney(..))"/><aop:advisoradvice-ref="txAdvice"pointcut-ref="transferPointcut"/></aop:config>
在上面的配置文件中,首先聲明了事務管理器transactionManager
,然后定義了事務通知txAdvice
,該通知會在transferMoney
方法執行時進行事務管理。最后通過aop:config
和aop:advisor
來將txAdvice
應用于transferPointcut
定義的切入點上。
聲明式事務的優點是通過配置文件來管理事務,避免了在代碼中手動控制事務的繁瑣和容易出錯的問題。不過缺點是靈活性較差,不能根據具體的業務需求來靈活控制事務的行為。
聲明式事務注解方式
Spring聲明式事務也可以通過注解的方式來實現。具體來說,可以在需要使用事務的方法上添加@Transactional
注解,并通過該注解的屬性來指定事務的傳播機制、隔離級別、超時時間等信息。
@Transactional(propagation=Propagation.REQUIRED,isolation=Isolation.DEFAULT,timeout=3600)publicvoidtransferMoney(AccountfromAccount,AccounttoAccount,doubleamount){fromAccount.withdraw(amount);toAccount.deposit(amount);}
在上面的代碼中,通過@Transactional
注解來聲明了事務的傳播機制為Propagation.REQUIRED
,隔離級別為Isolation.DEFAULT
,超時時間為3600秒。在方法執行時,Spring會根據注解中的信息自動管理事務的行為。
注解式聲明事務的優點是代碼簡潔、可讀性好,靈活性和可用性高,容易維護和調試。但是它也有一些缺點,例如注解的使用可能會導致代碼分散,而且無法通過配置文件來管理事務,而且可能會引入一些意想不到的問題。
@Transactional
注解的常用參數包括:value
:該屬性可以用來指定事務管理器的名稱,如果只有一個事務管理器,則可以省略該屬性。
propagation
:該屬性用于指定事務的傳播機制,包括REQUIRED
、SUPPORTS
、MANDATORY
、REQUIRES_NEW
、NOT_SUPPORTED
、NEVER
和NESTED
共7種。
isolation
:該屬性用于指定事務的隔離級別,包括DEFAULT
、READ_UNCOMMITTED
、READ_COMMITTED
、REPEATABLE_READ
和SERIALIZABLE
共5種。
timeout
:該屬性用于指定事務的超時時間,單位為秒,默認值為-1,表示沒有超時限制。
readOnly
:該屬性用于指定事務是否為只讀事務,默認值為false,表示事務可讀可寫。
rollbackFor
:該屬性用于指定事務回滾的條件,如果出現指定的異常類型,則事務會回滾。
noRollbackFor
:該屬性用于指定事務不回滾的條件,如果出現指定的異常類型,則事務不會回滾。
除了上述常用參數外,@Transactional
注解還有其他一些參數,例如transactionManager
、rollbackForClassName
、noRollbackForClassName
和value
等,具體用法可以參考Spring官方文檔。
在使用@Transactional
注解時,需要根據具體的業務需求來選擇合適的參數,以保證事務的正確性和可靠性。
Spring的聲明式事務注解可能失效的情況包括:
注解被錯誤地放置在了類上而不是方法上。
方法是private或final的,而且它們不能從外部調用。
方法沒有被公開暴露,也就是說,它們不是公開的方法(public)。
被注解的方法是靜態的。
被注解的方法依賴于其他未被注解的方法(例如,被注解的方法調用了一個未被注解的私有方法)。
被注解的方法在另一個類中被調用。
注解被錯誤地配置了,例如使用了錯誤的名稱或參數。
類沒有被正確地掃描,因此Spring無法找到應該被注解的方法。
注解屬性propagation設置錯誤
注解屬性rollbackFor設置錯誤
異常被catch捕獲導致@Transactional失效
數據庫引擎不支持事務
多個切面的影響也會導致事務失效
如果遇到聲明式事務注解失效的情況,需要檢查上述問題并進行相應的修復。
代碼規范中強調
@Transactional事務不要濫用。事務會影響數據庫的QPS,另外使用事務的敵方需要考慮各方面的回滾方案,包括緩存回滾、搜索引擎、消息補償、統計修正等。
在使用Spring事務時,需要注意對于事務的傳播機制和隔離級別的設置,以及對于事務的異常處理等問題。正確地使用Spring事務可以提高系統的數據一致性和可靠性。
Spring事務傳播機制是指在多個事務操作發生時,如何管理這些操作之間的事務關系。Spring事務傳播機制可以通過Propagation
枚舉類中的不同值來指定,共包括七種不同的傳播行為。具體來說,Spring事務傳播機制包括以下七種:
REQUIRED
:如果當前沒有事務,則創建一個新的事務;如果當前已經存在事務,則加入該事務。這是默認的傳播行為。
SUPPORTS
:如果當前存在事務,則加入該事務;如果當前沒有事務,則以非事務的方式執行。
MANDATORY
:必須在一個已存在的事務中執行,否則就拋出TransactionRequiredException
異常。
REQUIRES_NEW
:創建一個新的事務,并在該事務中執行;如果當前存在事務,則將當前事務掛起。
NOT_SUPPORTED
:以非事務方式執行操作,如果當前存在事務,則將當前事務掛起。
NEVER
:以非事務方式執行操作,如果當前存在事務,則拋出IllegalTransactionStateException
異常。
NESTED
:如果當前存在事務,則在嵌套事務中執行;如果當前沒有事務,則創建一個新的事務。
在使用Spring事務傳播機制時,需要根據具體的業務需求來選擇合適的傳播行為,以保證事務的正確性和可靠性。同時,需要注意事務的異常處理等問題,以避免數據不一致或丟失的情況發生。
@Transactional
注解中的傳播機制除了在代碼中使用編程式事務和聲明式事務外,Spring還提供了@Transactional
注解來實現事務控制。在使用@Transactional
注解時,可以通過propagation
屬性來指定事務的傳播機制,例如:
@Transactional(propagation=Propagation.REQUIRED)publicvoidtransferMoney(AccountfromAccount,AccounttoAccount,doubleamount){fromAccount.withdraw(amount);toAccount.deposit(amount);}
在上面的代碼中,通過propagation
屬性來指定了事務的傳播機制為Propagation.REQUIRED
,即如果當前沒有事務,則創建一個新的事務;如果當前已經存在事務,則加入該事務。
除了Propagation
枚舉類中的七種傳播行為外,@Transactional
注解還可以通過isolation
、timeout
、readOnly
等屬性來指定事務的隔離級別、超時時間和只讀事務等信息。
在使用@Transactional
注解時,需要根據具體的業務需求來選擇合適的傳播行為和其他屬性,以保證事務的正確性和可靠性。
Spring事務的隔離級別是指多個事務之間的隔離程度,它可以通過設置isolation
屬性來指定。Spring事務的隔離級別包括以下五種:
DEFAULT
:默認的隔離級別,由底層數據庫引擎決定。
READ_UNCOMMITTED
:最低的隔離級別,允許讀取未提交的數據。該級別會導致“臟讀”、“不可重復讀”和“幻讀”等問題。
READ_COMMITTED
:只允許讀取已經提交的數據。該級別可以避免“臟讀”,但可能會導致“不可重復讀”和“幻讀”等問題。
REPEATABLE_READ
:保證在同一個事務中多次讀取同一數據時,該數據的值不會發生變化。該級別可以避免“臟讀”和“不可重復讀”,但可能會導致“幻讀”等問題。
SERIALIZABLE
:最高的隔離級別,強制事務串行執行,避免了“臟讀”、“不可重復讀”和“幻讀”等問題。但是該級別會對性能產生較大的影響,因此一般不建議使用。
在選擇隔離級別時,需要根據具體的業務需求來選擇合適的級別。一般來說,如果不需要在事務中讀取未提交的數據,那么可以選擇READ_COMMITTED
級別;如果需要避免“不可重復讀”問題,可以選擇REPEATABLE_READ
級別;如果需要避免“幻讀”問題,可以選擇SERIALIZABLE
級別。但是需要注意的是,隔離級別越高,事務的并發性越差,因此需要根據具體業務場景來權衡隔離級別和性能。
不可重復讀和幻讀都是在并發讀寫數據時可能出現的問題。
不可重復讀指的是在一個事務中多次讀取同一數據,但是由于其他事務的修改,導致兩次讀取的結果不一致。例如,事務A在讀取某個數據時,事務B修改了該數據并提交,然后事務A再次讀取該數據時,得到了不同的結果。
幻讀是指在一個事務中多次讀取同一范圍內的數據,但是由于其他事務的插入操作,導致兩次讀取的結果不一致。例如,事務A在讀取某個范圍內的數據時,事務B插入了一條數據并提交,然后事務A再次讀取該范圍內的數據時,得到了不同的結果。
不可重復讀和幻讀的區別在于,不可重復讀是在讀取同一數據時出現問題,而幻讀是在讀取同一范圍內的數據時出現問題。解決不可重復讀的問題可以使用鎖機制或者提高事務的隔離級別,而解決幻讀的問題可以使用鎖機制或者使用更高的隔離級別,例如SERIALIZABLE
級別。
rollbackFor
屬性在使用@Transactional
注解進行聲明式事務管理時,可以通過rollbackFor
屬性來指定哪些異常類型需要回滾事務。需要注意的是,rollbackFor
屬性指定的異常類型必須是Throwable
類型或其子類,并且必須包含在Spring
事務拋出的異常類型之內。如果指定的異常類型不正確或不在事務回滾的異常類型之內,可能會導致事務無法正確回滾或者回滾不完整的問題。
如果需要指定多個異常類型,可以使用數組的方式進行指定,例如:
@Transactional(rollbackFor={SQLException.class,IOException.class})publicvoiddoSomething(){//...}
在上面的代碼中,指定了SQLException
和IOException
兩種異常類型需要回滾事務。默認情況只有RuntimeException和Error會觸發事務回滾。
除了rollbackFor
屬性外,@Transactional
注解還有其他一些屬性可以用于指定事務的屬性和行為,包括propagation
、isolation
、timeout
、readOnly
等。需要根據具體的業務需求來選擇合適的屬性和行為,以保證事務的正確性和可靠性。
感謝各位的閱讀,以上就是“Spring事務是什么及怎么實現”的內容了,經過本文的學習后,相信大家對Spring事務是什么及怎么實現這一問題有了更深刻的體會,具體使用情況還需要大家實踐驗證。這里是本站,小編將為大家推送更多相關知識點的文章,歡迎關注!
本文由 貴州做網站公司 整理發布,部分圖文來源于互聯網,如有侵權,請聯系我們刪除,謝謝!
c語言中正確的字符常量是用一對單引號將一個字符括起表示合法的字符常量。例如‘a’。數值包括整型、浮點型。整型可用十進制,八進制,十六進制。八進制前面要加0,后面...
2022年天津專場考試原定于3月19日舉行,受疫情影響確定延期,但目前延期后的考試時間推遲。 符合報名條件的考生,須在規定時間登錄招考資訊網(www.zha...
:喜歡聽,樂意看。指很受歡迎?!巴卣官Y料”喜聞樂見:[ xǐ wén lè jiàn ]詳細解釋1. 【解釋】:喜歡聽,樂意看。指很受歡迎。2. 【示例】:這是...
什么是淘寶搜索指數?淘寶搜索指數指的是衡量一款特定的產品冷熱程度的一個重要的指標。其形成也并不是完全只是按照商品被搜索的次數來進行設置的,根據一定的搜索比例來警醒分析。同時淘寶搜索指數的變化,也可以直接反應出一款商品的熱度和競爭程度的變化。淘寶搜索指數有什么用啊?淘寶搜索指數是店鋪運營過程中非常重要的數據,對店鋪運營有著重要的作用。它體現在三個方面:1.有利于調整門店經營的產品類型。淘寶搜索指數其...
銀證轉賬時間要多久?銀證轉賬實時到賬,并且沒有金額限制和不收手續費,只要在規定時間內轉賬即可。銀證轉賬時間為:周一至周五上午9: 00到下午16:00點,部分券商上午8: 30就能進行銀證轉賬,法定節假日除外。要注意的是當天賣出股票,資金可用不可取,資金當天可以繼續交易股票、基金等,轉出需要到第二個交易日。銀證轉賬轉到銀行卡多長時間?最快當天就到。其實銀證轉賬牽涉到證券資金賬戶和銀行賬戶的結算問題...
2018年股市為什么大跌?2018年12月28日是2018年a股的最后一個交易日。這一年,a股相當跌宕起伏。對于投資者來說,他們度過了悲傷的2018年,但對于一些企業來說,他們度過了悲慘的2018年。2018的股市已經讓人走的很艱難了。a股三大指數今年以來跌幅均超過20%,而個股情況更為慘烈。根據相關統計可以知道,2018年中,除了股價遭遇腰斬,還有3200多只股票收跌,共有503只股票跌幅超過5...