Spring 之注解事務 @Transactional

前些天發現了一個巨牛的人工智能學習網站,通俗易懂,風趣幽默,忍不住分享一下給大家。點擊跳轉到教程。

先讓我們看代碼吧!
以下代碼為在“Spring3事務管理——基于tx/aop命名空間的配置”基礎上修改。首先修改applicationContext.xml如下:

?
?
[html]?view plain?copy
  1. <!--?定義一個數據源?-->??
  2. <bean?id="dataSource"?class="org.apache.tomcat.jdbc.pool.DataSource">??
  3. ????????<property?name="driverClassName"?value="com.mysql.jdbc.Driver"?/>??
  4. ????????<property?name="url"?value="jdbc:mysql://localhost:3306/spring_test"?/>??
  5. ????????<property?name="username"?value="root"?/>??
  6. ????????<property?name="password"?value="root"?/>??
  7. </bean>??
  8. ???
  9. <!--?定義JdbcTemplate的Bean?-->??
  10. <bean?id="jdbcTemplate"?class="org.springframework.jdbc.core.JdbcTemplate"??
  11. ????????p:dataSource-ref="dataSource">??
  12. </bean>??
  13. ???
  14. <!--?配置事務管理器?-->??
  15. <bean?id="txManager"??
  16. ????????class="org.springframework.jdbc.datasource.DataSourceTransactionManager"??
  17. ????????p:dataSource-ref="dataSource">??
  18. </bean>??
  19. ???
  20. <!--?enables?scanning?for?@Transactional?annotations?-->??
  21. <tx:annotation-driven?transaction-manager="txManager"?/>??
  22. ???
  23. <!--?在該Bean的代碼中標注@Transactional可以被事務管理器注入?-->??
  24. <bean?id="userScore"??
  25. ????????class="net.hingyi.springDemo.transaction.service.UserScoreServiceImpl"??
  26. ????????p:userScoreRepository-ref="userScoreRepository_jdbc"?/>??
  27. ???
  28. <bean?id="userScoreRepository_jdbc"??
  29. ????????class="net.hingyi.springDemo.transaction.repository.UserScoreRepositoryImpl"??
  30. ????????p:jdbcTemplate-ref="jdbcTemplate"?/>??



實現類代碼:

?

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
@Transactional
publicclassUserScoreRepositoryImpl?implementsUserScoreRepository {
????privateJdbcTemplate jdbcTemplate;
????@Override
????publicUserScore getUserSocore(String userNo) {
????finalUserScore us =?newUserScore();
????...
????returnus;
????}
????...
}

OK了!以上就實現了簡單的事務管理了。現在再稍微了解下@Transactional。
在配置文件中,默認情況下,<tx:annotation-driven>會自動使用名稱為transactionManager的事務管理器。所以,如果定義的事務管理器名稱為transactionManager,那么就可以直接使用<tx:annotation-driven/>。如下:

?
1
2
3
4
5
6
7
8
<!-- 配置事務管理器 -->
<beanid="transactionManager"
????class="org.springframework.jdbc.datasource.DataSourceTransactionManager"
????p:dataSource-ref="dataSource">
</bean>
<!-- enables scanning for @Transactional annotations -->
<tx:annotation-driven/>

<tx:annotation-driven>一共有四個屬性如下,

  • mode:指定Spring事務管理框架創建通知bean的方式。可用的值有proxy和aspectj。前者是默認值,表示通知對象是個JDK代理;后者表示Spring AOP會使用AspectJ創建代理?
  • proxy-target-class:如果為true,Spring將創建子類來代理業務類;如果為false,則使用基于接口的代理。(如果使用子類代理,需要在類路徑中添加CGLib.jar類庫)?
  • order:如果業務類除事務切面外,還需要織入其他的切面,通過該屬性可以控制事務切面在目標連接點的織入順序。?
  • transaction-manager:指定到現有的PlatformTransaction Manager bean的引用,通知會使用該引用?

?@Transactional的屬性

屬性名?

類型?

說明?

isolation?

枚舉org.springframework.transaction.annotation.Isolation的值?

事務隔離級別?

noRollbackFor?

Class<? extends Throwable>[]?

一組異常類,遇到時不回滾。默認為{}

noRollbackForClassName?

Stirng[]?

一組異常類名,遇到時不回滾,默認為{}

propagation?

枚舉org.springframework.transaction.annotation.Propagation的值?

事務傳播行為?

readOnly?

boolean?

事務讀寫性?

rollbackFor?

Class<? extends Throwable>[]?

一組異常類,遇到時回滾?

rollbackForClassName?

Stirng[]?

一組異常類名,遇到時回滾?

timeout?

int?

超時時間,以秒為單位?

value?

String?

可選的限定描述符,指定使用的事務管理器?

@Transactional標注的位置
@Transactional注解可以標注在類和方法上,也可以標注在定義的接口和接口方法上。
如果我們在接口上標注@Transactional注解,會留下這樣的隱患:因為注解不能被繼承,所以業務接口中標注的@Transactional注解不會被業務實現類繼承。所以可能會出現不啟動事務的情況。所以,Spring建議我們將@Transaction注解在實現類上。
在方法上的@Transactional注解會覆蓋掉類上的@Transactional。

使用不同的事務管理器
如果我們要程序中使用多個事務管理器(主要是針對多數據源的情況),可以通過以下的方式實現:
Service代碼:

?
1
2
3
4
5
6
7
8
9
10
11
publicclassMultiTxService {
????@Transactional("tran_1")
????publicvoidaddTest(intid){
?????????
????}
????@Transactional("tran_2")
????publicvoiddeleteTest(intid){
?????????
????}
}

applicationContext.xml配置如下:?

?
1
2
3
4
5
6
7
8
9
10
<beanid="tran_1"
????class="org.springframework.jdbc.datasource.DataSourceTransactionManager"
????p:dataSource-ref="dataSource">
????<qualifiervalue="tran_1"/>
</bean>
<beanid="tran_2"
????class="org.springframework.jdbc.datasource.DataSourceTransactionManager"
????p:dataSource-ref="dataSource">
????<qualifiervalue="tran_2"/>
</bean>

經過以上的代碼,每個事務都會綁定各自的獨立的數據源,進行各自的事務管理。我們可以優化下以上代碼,可以自定義一個綁定到特定事務管理器的注解,然后直接使用這個自定義的注解進行標識:

?

?
1
2
3
4
5
6
@Target({ElementType.METHOD,ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Transactional("tran_1")
public@interfaceCustomerTransactional {
}

在Service代碼中使用:

?
1
2
3
4
5
6
7
...
//使用名為tran_1的事務管理器
@CustomerTransactional
public void addTest(String str){
?????
}

Spring在TransactionDefinition接口中規定了7種類型的事務傳播行為,

它們規定了事務方法和事務方法發生嵌套調用時事務如何進行傳播:

事務傳播行為類型

事務傳播行為類型

說明

PROPAGATION_REQUIRED

如果當前沒有事務,就新建一個事務,如果已經存在一個事務中,加入到這個事務中。這是最常見的選擇。

PROPAGATION_SUPPORTS

支持當前事務,如果當前沒有事務,就以非事務方式執行。

PROPAGATION_MANDATORY

使用當前的事務,如果當前沒有事務,就拋出異常。

PROPAGATION_REQUIRES_NEW

新建事務,如果當前存在事務,把當前事務掛起。

PROPAGATION_NOT_SUPPORTED

以非事務方式執行操作,如果當前存在事務,就把當前事務掛起。

PROPAGATION_NEVER

以非事務方式執行,如果當前存在事務,則拋出異常。

PROPAGATION_NESTED

如果當前存在事務,則在嵌套事務內執行。如果當前沒有事務,則執行與PROPAGATION_REQUIRED類 似的操作。

?

?

復制代碼
spring 事務注解默認遇到throw new RuntimeException("...");會回滾
需要捕獲的throw new Exception("...");不會回滾// 指定回滾
@Transactional(rollbackFor=Exception.class) public void methodName() {// 不會回滾throw new Exception("...");} 
//指定不回滾
@Transactional(noRollbackFor=Exception.class)public ItimDaoImpl getItemDaoImpl() {// 會回滾throw new RuntimeException("注釋");} // 如果有事務,那么加入事務,沒有的話新建一個(不寫的情況下)@Transactional(propagation=Propagation.REQUIRED) // 容器不為這個方法開啟事務@Transactional(propagation=Propagation.NOT_SUPPORTED)// 不管是否存在事務,都創建一個新的事務,原來的掛起,新的執行完畢,繼續執行老的事務@Transactional(propagation=Propagation.REQUIRES_NEW) // 必須在一個已有的事務中執行,否則拋出異常@Transactional(propagation=Propagation.MANDATORY)// 必須在一個沒有的事務中執行,否則拋出異常(與Propagation.MANDATORY相反)@Transactional(propagation=Propagation.NEVER) // 如果其他bean調用這個方法,在其他bean中聲明事務,那就用事務.如果其他bean沒有聲明事務,那就不用事務.@Transactional(propagation=Propagation.SUPPORTS) /*public void methodName(){// 本類的修改方法 1update();// 調用其他類的修改方法otherBean.update();// 本類的修改方法 2update();}other失敗了不會影響 本類的修改提交成功本類update的失敗,other也失敗*/
@Transactional(propagation=Propagation.NESTED) 
// readOnly=true只讀,能插入,但不能更新,刪除 
@Transactional (propagation = Propagation.REQUIRED,readOnly=true) 
// 設置超時時間
@Transactional (propagation = Propagation.REQUIRED,timeout=30)
// 設置數據庫隔離級別
@Transactional (propagation = Propagation.REQUIRED,isolation=Isolation.DEFAULT)
復制代碼

?

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/450824.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/450824.shtml
英文地址,請注明出處:http://en.pswp.cn/news/450824.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

超級程序員神話

摘要&#xff1a;大部分的程序員在思想里都會某種程度的承認&#xff0c;承認自己只是一個普通的程序員&#xff0c;但這世界上確實有一些超級程序員&#xff0c;在一個為企業開發應用的程序員和一個為谷歌寫搜索算法的程序員之間&#xff0c;或和一個開發用來控制讀寫頭從磁盤…

HashMap30連問,徹底搞懂HashMap

文章目錄一、背景知識1、什么是Map&#xff1f;2、什么是Hash&#xff1f;3、什么是哈希表&#xff1f;4、什么是HashMap?5、如何使用HashMap&#xff1f;6、HashMap有哪些核心參數&#xff1f;7、HashMap與HashTable的對比&#xff1f;8、HashMap和HashSet的區別&#xff1f;…

博弈論的算法總結

開頭先啰嗦一句&#xff1a;想學好博弈&#xff0c;必然要花費很多的時間&#xff0c;深入學習&#xff0c;不要存在一知半解&#xff0c;應該是一看到題目&#xff0c;就想到博弈的類型。 以及&#xff0c;想不斷重復不斷重復&#xff0c;做大量各大oj網站的題目&#xff0c;最…

Slog55_lua面向對象之lua類

Slog55_lua面向對象之lua類 ArthurSlog SLog-55 Year1 GuangzhouChina Aug 30th 2018 微信掃描二維碼&#xff0c;關注我的公眾號GitHub 掘金主頁 簡書主頁 segmentfault 現實中的事情不是根據人的喜好而定的 比如長在你嘴里的智齒 大部分情況下 你會因為自己&#xff0…

Spring中的@scope注解

前些天發現了一個巨牛的人工智能學習網站&#xff0c;通俗易懂&#xff0c;風趣幽默&#xff0c;忍不住分享一下給大家。點擊跳轉到教程。 Scope 簡單點說就是用來指定bean的作用域作用域 &#xff08;官方解釋&#xff1a;scope用來聲明IOC容器中的對象應該處的限定場景或者…

編程語言大比拼——誰的效率高

摘要&#xff1a;C、C、Java這幾個屹立不倒的開發語言&#xff0c;如果以功能點作為單位的話&#xff0c;誰的效率最高呢&#xff1f;如果在項目初期就能確定功能點數量&#xff0c;那么就可以很好的預測項目完成時間。這一點是不是對你很有幫助呢&#xff1f; 一份6000個項目的…

Hadoop之Flume詳解

1、日志采集框架Flume   1.1 Flume介紹     Flume是一個分布式、可靠、和高可用的海量日志采集、聚合和傳輸的系統。     Flume可以采集文件&#xff0c;socket數據包等各種形式源數據&#xff0c;又可以將采集到的數據輸出到HDFS、hbase、hive、     kafka等眾多…

搞懂Java的反射機制

搞懂Java的反射機制 1.什么是反射&#xff1f; java的反射機制是指可以在運行狀態下獲取類和對象的所有屬性和方法。 2.反射的作用&#xff1f; 1、在運行時獲取一個類/對象的成員變量和方法 2、在運行時創建一個類的對象 3、在運行時判斷一個對象是否屬于一個類 3.反射有哪些…

表單oninput和onchange事件區別

oninput事件是元素value發生變化是立刻觸發&#xff0c;而onchange是元素發生變化并且失去焦點時才會觸發。 轉載于:https://www.cnblogs.com/ykli/p/9565601.html

Struts2中<s:iterator>基本用法及示例

前些天發現了一個巨牛的人工智能學習網站&#xff0c;通俗易懂&#xff0c;風趣幽默&#xff0c;忍不住分享一下給大家。點擊跳轉到教程。 Struts2中<s:iterator>基本用法及示例 Iterator用于遍歷集合&#xff08;java.util.Collection&#xff09;或枚舉值&#xff08;j…

如何使用postman做接口測試

1、get請求傳參 只要是get請求都可以在瀏覽器中直接發&#xff1a; 在訪問地址后面拼 ?keyvalue&keyvalue 例如&#xff1a;在瀏覽器中直接輸入訪問地址&#xff0c;后面直接拼需要傳給服務器的參數http://api.nnzhp.cn/api/user/stu_info?stu_name小黑2、post請求&…

【狂神說】分析前后端分離開源項目?

文章目錄1.如何分析開源項目項目簡介項目源碼2.觀察開源項目3.開源項目下載4.跑起來是第一步5.前后端分離項目固定套路6.如何找到一個開源項目1.如何分析開源項目 學習的方式&#xff1a; 不知道這個代碼怎么來的這個代碼跑不起來這個項目對我們有什么幫助&#xff0c;不會模…

設計公共API的六個注意事項

摘要&#xff1a;俗話說&#xff1a;“好東西就要貢獻出來和大家一起分享”&#xff0c;尤其是在互聯網業務高度發達的今天&#xff0c;如果你的創業公司提供了一項很酷的技術或者服務&#xff0c;并且其他用戶也非常喜歡該產品&#xff0c;在這種情況下&#xff0c;最好的解決…

go 交叉編譯

golang中windows交叉編譯 env GOOSlinux GOARCHamd64 go build .打包鏡像 FROM alpineMAINTAINER "congge"ADD ./casino_niuniu /usr/local/casino_niuniu/bin/casino_niuniu ADD ./templates /usr/loca/lcasino_niuniu/bin/templates ADD ./public /usr/local/casin…

IntelliJ Idea 2017 免費激活方法

見&#xff1a;https://www.cnblogs.com/suiyueqiannian/p/6754091.html 1. 到網站 http://idea.lanyus.com/ 獲取注冊碼。 2.填入下面的license server: http://intellij.mandroid.cn/   http://idea.imsxm.com/   http://idea.iteblog.com/key.php 以上方法驗證均可以

P3193 [HNOI2008]GT考試

傳送門 容易看出是道DP 考慮一位一位填數字 設 f [ i ] [ j ] 表示填到第 i 位&#xff0c;在不吉利串上匹配到第 j 位時不出現不吉利數字的方案數 設 g [ i ] [ j ] 表示不吉利串匹配到第 i 位&#xff0c;再添加一個數字&#xff0c;使串匹配到第 j 位的方案數 那么方程顯然為…

LeetCode刷題攻略

目錄 一、LeetCode簡介 二、刷leetcode的主要目的 三、常用的數據結構 四、常用的算法思想 五、選擇算法題 1、刷題選擇 2、刷題方法 方法一&#xff1a;順序法 方法二&#xff1a;標簽法 方法三&#xff1a;隨機法 方法四&#xff1a;必殺法 六、刷題攻略 TIP 1&…

SQLserver數據庫反編譯生成Hibernate實體類和映射文件

一、建立項目和sqlserver數據庫 eclipse&#xff0c;我使用的版本是neon3 二、Data Source Explorer 選擇OK 在data source Explorer的Database Connections 選擇New 填寫好General的連接信息 新建New Driver Definition 填寫完選擇OK 選擇剛才的Drivers Test Connetion測試 N…

最受歡迎的5大Linux發行版

摘要&#xff1a;要統計有多少人在使用那款Linux發行版幾乎是不可能的事情&#xff0c;但我們可以使用一些在線分析工具來大概地看看哪些Linux發行版更受歡迎。 Google Trends的數據顯示&#xff0c;Ubuntu用戶正在流向Mint&#xff0c;但依然在各方面都比其它Linux發行版更有優…

C#動態操作DataTable(新增行、列、查詢行、列等)

public void CreateTable(){//創建表DataTable dt new DataTable();//1、添加列dt.Columns.Add("Name", typeof(string)); //數據類型為 文本//2、通過列架構添加列DataColumn age new DataColumn("Age", typeof(Int32)); //數據類型為 整形DataColumn…