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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > java >内容正文

java

Java程序员从笨鸟到菜鸟之(八十)细谈Spring(九)spring+hibernate声明式事务管理详解

發布時間:2025/3/21 java 22 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Java程序员从笨鸟到菜鸟之(八十)细谈Spring(九)spring+hibernate声明式事务管理详解 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

聲明式事務管理是spring對事務管理的最常用的方式,因為這種方式對代碼的影響最小,因此也符合非侵入性的輕量級容器的概念。Spring的事務管理是通過AOP的方式來實現的,因為事務方面的代碼與spring的綁定并以一種樣板式結構使用。在理解spring聲明式事務管理我們首先要理解他是通過AOP怎么具體實現的。其中的事務通知由元數據(目前基于xml和注解)驅動。代理對象由元數據結合產生一個新的代理對象。他使用一個PlatformTransactionManager實現配合TransactionInterceptor在方法調用之前實施事務。下面我們就通過一個圖來看一下spring聲明式事務管理的執行過程。

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?

下面我們就以一個spring官方文檔所給的例子來具體看一下用xml配置方式怎么來實現聲明式事務管理:


首先請看下面的接口和它的實現。這個例子的意圖是介紹概念:

//?我們想做成事務性的服務接口

[java]?view plaincopy print?
  • package?x.y.service;??
  • public?interface?FooService?{??
  • ??Foo?getFoo(String?fooName);??
  • ??Foo?getFoo(String?fooName,?String?barName);??
  • ??void?insertFoo(Foo?foo);??
  • ??void?updateFoo(Foo?foo);??
  • }??


  • //?上述接口的一個實現

    [java]?view plaincopy print?
  • package?x.y.service;??
  • public?class?DefaultFooService?implements?FooService?{??
  • ??public?Foo?getFoo(String?fooName)?{??
  • ????throw?new?UnsupportedOperationException();??
  • ??}??
  • ??public?Foo?getFoo(String?fooName,?String?barName)?{??
  • ????throw?new?UnsupportedOperationException();??
  • ??}??
  • ??public?void?insertFoo(Foo?foo)?{??
  • ????throw?new?UnsupportedOperationException();??
  • ??}??
  • ??public?void?updateFoo(Foo?foo)?{??
  • ????throw?new?UnsupportedOperationException();??
  • ??}}??


  • ? ? ? ?首先要解釋的是很多同學可能都在考慮這個事務管理到底是放在dao層還是放在service層呢。這個問題我想大多數童鞋的反應應該都是在dao層上吧,剛開始我也是這么想的。但是大家想想,如果我們要進行兩個甚至多個dao層中的方法操作,并且要求放在同一個事務里時,我們該怎么來管理這個事務呢,這時我們就沒辦法了。所以我們應該把事務管理放在service層中,我們直接在service層中調用這兩個dao層的方法就oK了。

    ? ? ? 下面我們接著往下看,我們假定,FooService的前兩個方法(getFoo(String)?和getFoo(String,?String))必須執行在只讀事務上下文中,其他的方法(insertFoo(Foo)和?updateFoo(Foo))必須執行在可讀寫事務上下文中。我們根據這個要求來看一下配置文件,我們剛開始可能看不懂,不用慌,往下我們會一一解釋的。

    [html]?view plaincopy print?
  • <!--?from?the?file?'context.xml'?-->??
  • <?xml?version="1.0"?encoding="UTF-8"?>??
  • <beans?xmlns="http://www.springframework.org/schema/beans"??
  • ?????xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"??
  • ?????xmlns:aop="http://www.springframework.org/schema/aop"??
  • ?????xmlns:tx="http://www.springframework.org/schema/tx"??
  • ?????xsi:schemaLocation="??
  • ?????http://www.springframework.org/schema/beans?http://www.springframework.org/schema/beans/spring-beans-2.5.xsd??
  • ?????http://www.springframework.org/schema/tx?http://www.springframework.org/schema/tx/spring-tx-2.5.xsd??
  • ?????http://www.springframework.org/schema/aop?http://www.springframework.org/schema/aop/spring-aop-2.5.xsd">??
  • ????
  • ??<!--?this?is?the?service?object?that?we?want?to?make?transactional?-->??
  • ??<bean?id="fooService"?class="x.y.service.DefaultFooService"/>??
  • ??<!--?the?transactional?advice?(what?'happens';?see?the?<aop:advisor/>?bean?below)?-->??
  • ??<tx:advice?id="txAdvice"?transaction-manager="txManager">??
  • ??<!--?the?transactional?semantics...?-->??
  • ??<tx:attributes>??
  • ????<!--?all?methods?starting?with?'get'?are?read-only?-->??
  • ????<tx:method?name="get*"?read-only="true"/>??
  • ????<!--?other?methods?use?the?default?transaction?settings?(see?below)?-->??
  • ????<tx:method?name="*"/>??
  • ??</tx:attributes>??
  • ??</tx:advice>??
  • ????
  • ??<!--?ensure?that?the?above?transactional?advice?runs?for?any?execution??
  • ????of?an?operation?defined?by?the?FooService?interface?-->??
  • ??<aop:config>??
  • ??<aop:pointcut?id="fooServiceOperation"?expression="execution(*?x.y.service.FooService.*(..))"/>??
  • ??<aop:advisor?advice-ref="txAdvice"?pointcut-ref="fooServiceOperation"/>??
  • ??</aop:config>??
  • ????
  • ??<!--?don't?forget?the?DataSource?-->??
  • ??<bean?id="dataSource"?class="org.apache.commons.dbcp.BasicDataSource"?destroy-method="close">??
  • ??<property?name="driverClassName"?value="oracle.jdbc.driver.OracleDriver"/>??
  • ??<property?name="url"?value="jdbc:oracle:thin:@rj-t42:1521:elvis"/>??
  • ??<property?name="username"?value="scott"/>??
  • ??<property?name="password"?value="tiger"/>??
  • ??</bean>??
  • ??<!--?similarly,?don't?forget?the?PlatformTransactionManager?-->??
  • ??<bean?id="txManager"?class="org.springframework.jdbc.datasource.DataSourceTransactionManager">??
  • ??<property?name="dataSource"?ref="dataSource"/>??
  • ??</bean>???
  • ??<!--?other?<bean/>?definitions?here?-->??
  • </beans>??


  • ? ? ? ?好了,配置一大片,什么東西,我也看不懂,呵呵,沒關系,一會大家就明白了,我們先來看一下官方給的解釋,然后我在根據我自己的理解給大家通俗的解釋一下這里的內容。

    ? ? ???? ? 我們要把一個服務對象('fooService' bean)做成事務性的。 我們想施加的事務語義封裝在<tx:advice/>定義中。<tx:advice/> “把所有以 'get' 開頭的方法看做執行在只讀事務上下文中, 其余的方法執行在默認語義的事務上下文中”。 其中的 'transaction-manager' 屬性被設置為一個指向 PlatformTransactionManager bean的名字(這里指 'txManager'), 該bean將會真正管理事務。配置中最后一段是 <aop:config/> 的定義, 它確保由 'txAdvice' bean定義的事務通知在應用中合適的點被執行。 首先我們定義了 一個切面,它匹配 FooService 接口定義的所有操作, 我們把該切面叫做 'fooServiceOperation'。然后我們用一個通知器(advisor)把這個切面與 'txAdvice' 綁定在一起, 表示當 'fooServiceOperation' 執行時,'txAdvice' 定義的通知邏輯將被執行。


    ? ? ? ? 好了,上面就是官方文檔給出的這個配置文件的解釋,不知道大家有沒有看懂,反正對于初學者我的時候,我是真沒看懂,不太容易懂,當然了,大牛們是一定能看懂的。下面我就根據我自己的理解來通俗的講解一下。

    ? ? ? ?首先我們應該要把服務對象'fooService'?聲明成一個bean我們要把一個服務對象('fooService'?bean)做成事務性的。我們就應該首先在聲明一個事務管理的建議,用什么來管理,spring給我們提供了事務封裝,這個就封裝在了<tx:advice/>中,這個事務建議給我們提供了一個transaction-manager屬性,用他可以指定我們用誰來管理我們的事務。我們上邊的例子用的為一個指向?PlatformTransactionManager?bean的名字(這里指?'txManager'),?該bean將會真正管理事務。上面用的事務管理類是用的jdbc中提供的事務管理,當然這里也可以指定為hibernate管理。當然了,不管用那個類來管理我們的事務,都不要忘記了提供我們的datasource屬性,因為事務管理也需要這里面的信息。我們聲明好事務建議,也指定好了具體用哪個類來管理了,下面我們的任務就是要把我們定義好的這些利用AOP把我們的事務管理織入到我們的業務邏輯里面。<aop:config/>?的定義,?它確保由?'txAdvice'??bean定義的事務通知在應用中合適的點被執行。?首先我們定義了?一個切面,它匹配?FooService?接口定義的所有操作,?我們把該切面叫做?'fooServiceOperation'。<aop:pointcut/>?元素定義是AspectJ的切面表示法,上述表示x.y.service.FooService包下的任意方法。然后我們用一個通知器(advisor)把這個切面與?'txAdvice'?綁定在一起,?表示當?'fooServiceOperation'?執行時,'txAdvice'?定義的通知邏輯將被執行。大體流程就是這樣的了。

    ??????上面的配置將為'fooService'?bean創建一個代理對象,這個代理對象被裝配了事務通知,所以當它的相應方法被調用時,一個事務將被啟動、掛起、被標記為只讀,或者其它(根據該方法所配置的事務語義)。

    我們來看看下面的例子,測試一下上面的配置。

    [java]?view plaincopy print?
  • public?final?class?Boot?{??
  • ??public?static?void?main(final?String[]?args)?throws?Exception?{??
  • ????ApplicationContext?ctx?=?new?ClassPathXmlApplicationContext("context.xml",?Boot.class);??
  • ????FooService?fooService?=?(FooService)?ctx.getBean("fooService");??
  • ????fooService.insertFoo?(new?Foo());??
  • ??}}??


  • 運行可以清楚的看到如下結果:

    -?Invoking?rollback?for?transaction?on?x.y.service.FooService.insertFoo????????

    due?to?throwable?[Java.lang.UnsupportedOperationException]

    <tx:advice/>?有關的設置

    通過?<tx:advice/>?標簽來指定不同的事務性設置。默認的?<tx:advice/>?設置如下:

    事務傳播設置是?REQUIRED

    隔離級別是DEFAULT

    事務是?讀/

    事務超時默認是依賴于事務系統的,或者事務超時沒有被支持。

    任何?RuntimeException?將觸發事務回滾,但是任何?checked?Exception?將不觸發事務回滾

    這些默認的設置當然也是可以被改變的。?<tx:advice/>?和?<tx:attributes/>?標簽里的?<tx:method/>?各種屬性設置總結如下:

    Table?9.1.?<tx:method/>?有關的設置

    屬性

    是否需要?

    默認值

    描述

    name

    與事務屬性關聯的方法名。通配符(*)可以用來指定一批關聯到相同的事務屬性的方法。?如:'get*''handle*''on*Event'等等。

    propagation

    REQUIRED

    事務傳播行為

    isolation

    DEFAULT

    事務隔離級別

    timeout

    -1

    事務超時的時間(以秒為單位)

    read-only

    false

    事務是否只讀?

    rollback-for

    將被觸發進行回滾的?Exception(s);以逗號分開。?如:'com.foo.MyBusinessException,ServletException'

    no-rollback-for

    不?被觸發進行回滾的?Exception(s);以逗號分開。?如:'com.foo.MyBusinessException,ServletException'


    下面我們具體來看一下事務的傳播性的幾個值:

    REQUIRED:業務方法需要在一個容器里運行。如果方法運行時,已經處在一個事務中,那么加入到這個事務,否則自己新建一個新的事務。
    NOT_SUPPORTED:聲明方法不需要事務。如果方法沒有關聯到一個事務,容器不會為他開啟事務,如果方法在一個事務中被調用,該事務會被掛起,調用結束后,原先的事務會恢復執行。
    REQUIRESNEW:不管是否存在事務,該方法總匯為自己發起一個新的事務。如果方法已經運行在一個事務中,則原有事務掛起,新的事務被創建。
    MANDATORY:該方法只能在一個已經存在的事務中執行,業務方法不能發起自己的事務。如果在沒有事務的環境下被調用,容器拋出例外。
    SUPPORTS:該方法在某個事務范圍內被調用,則方法成為該事務的一部分。如果方法在該事務范圍外被調用,該方法就在沒有事務的環境下執行。
    NEVER:該方法絕對不能在事務范圍內執行。如果在就拋例外。只有該方法沒有關聯到任何事務,才正常執行。
    NESTED:如果一個活動的事務存在,則運行在一個嵌套的事務中。如果沒有活動事務,則按REQUIRED屬性執行。它使用了一個單獨的事務,這個事務?擁有多個可以回滾的保存點。內部事務的回滾不會對外部事務造成影響。它只對DataSourceTransactionManager事務管理器起效。

    使用?@Transactional

    除了基于XML文件的聲明式事務配置外,你也可以采用基于注解式的事務配置方法。直接在Java源代碼中聲明事務語義的做法讓事務聲明和將受其影響的代碼距離更近了,而且一般來說不會有不恰當的耦合的風險,因為,使用事務性的代碼幾乎總是被部署在事務環境中。

    下面的例子很好地演示了?@Transactional?注解的易用性,隨后解釋其中的細節。先看看其中的類定義:

    [java]?view plaincopy print?
  • //?the?service?class?that?we?want?to?make?transactional??
  • @Transactional??
  • public?class?DefaultFooService?implements?FooService?{??
  • ??Foo?getFoo(String?fooName);??
  • ??Foo?getFoo(String?fooName,?String?barName);??
  • ??void?insertFoo(Foo?foo);??
  • ??void?updateFoo(Foo?foo);??
  • }??


  • 當上述的POJO定義在Spring?IoC容器里時,上述bean實例僅僅通過一?行xml配置就可以使它具有事務性的。如下:

    [html]?view plaincopy print?
  • <?xml?version="1.0"?encoding="UTF-8"?>??
  • <beans?xmlns="http://www.springframework.org/schema/beans"??
  • ?????xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"??
  • ?????xmlns:aop="http://www.springframework.org/schema/aop"??
  • ?????xmlns:tx="http://www.springframework.org/schema/tx"??
  • ?????xsi:schemaLocation="??
  • ?????http://www.springframework.org/schema/beans?http://www.springframework.org/schema/beans/spring-beans-2.5.xsd??
  • ?????http://www.springframework.org/schema/tx?http://www.springframework.org/schema/tx/spring-tx-2.5.xsd??
  • ?????http://www.springframework.org/schema/aop?http://www.springframework.org/schema/aop/spring-aop-2.5.xsd">??
  • ????
  • ??<bean?id="fooService"?class="x.y.service.DefaultFooService"/>??
  • ???<tx:annotation-driven?transaction-manager="txManager"/>??
  • ???<bean?id="txManager"?class="org.springframework.jdbc.datasource.DataSourceTransactionManager">??
  • ???<property?name="dataSource"?ref="dataSource"/>??
  • ??</bean>??
  • </beans>??



  • 注意:??實際上,如果你用?'transactionManager'?來定義?PlatformTransactionManager?bean的名字的話,你就可以忽略?<tx:annotation-driven/>?標簽里的?'transaction-manager'?屬性。?如果?PlatformTransactionManager?bean你要通過其它名稱來注入的話,你必須用?'transaction-manager'?屬性來指定它。


    ? ? ? 在多數情形下,方法的事務設置將被優先執行。在下列情況下,例如:?DefaultFooService?類在類的級別上被注解為只讀事務,但是,這個類中的?updateFoo(Foo)?方法的?@Transactional?注解的事務設置將優先于類級別注解的事務設置。

    [html]?view plaincopy print?
  • @Transactional(readOnly?=?true)??
  • public?class?DefaultFooService?implements?FooService?{??
  • ??public?Foo?getFoo(String?fooName)?{??
  • ????//?do?something??
  • ??}??
  • ????//?these?settings?have?precedence?for?this?method??
  • ????@Transactional(readOnly?=?false,?propagation?=?Propagation.REQUIRES_NEW)??
  • ????public?void?updateFoo(Foo?foo)?{??
  • ????????//?do?something??
  • ?????????
  • ????}??
  • }??


  • @Transactional?有關的設置


    @Transactional?注解是用來指定接口、類或方法必須擁有事務語義的元數據。?如:當一個方法開始調用時就開啟一個新的只讀事務,并停止掉任何現存的事務”。?默認的?@Transactional?設置如下:

    事務傳播設置是?PROPAGATION_REQUIRED

    事務隔離級別是?ISOLATION_DEFAULT

    事務是?讀/

    事務超時默認是依賴于事務系統的,或者事務超時沒有被支持。

    任何?RuntimeException?將觸發事務回滾,但是任何?checked?Exception?將不觸發事務回滾

    這些默認的設置當然也是可以被改變的。?@Transactional?注解的各種屬性設置總結如下:

    ?@Transactional?注解的屬性

    屬性

    類型

    描述

    propagation

    枚舉型:Propagation

    可選的傳播性設置

    isolation

    枚舉型:Isolation

    可選的隔離性級別(默認值:ISOLATION_DEFAULT

    readOnly

    布爾型

    讀寫型事務?vs.?只讀型事務

    timeout

    int型(以秒為單位)

    事務超時

    rollbackFor

    一組?Class?類的實例,必須是Throwable?的子類

    一組異常類,遇到時?必須?進行回滾。默認情況下checked?exceptions不進行回滾,僅unchecked?exceptions(即RuntimeException的子類)才進行事務回滾。

    rollbackForClassname

    一組?Class?類的名字,必須是Throwable的子類

    一組異常類名,遇到時?必須?進行回滾

    noRollbackFor

    一組?Class?類的實例,必須是Throwable?的子類

    一組異常類,遇到時?必須不?回滾。

    noRollbackForClassname

    一組?Class?類的名字,必須是Throwable?的子類

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

    ? ? ?在寫代碼的時候,不可能對事務的名字有個很清晰的認識,這里的名字是指會在事務監視器(比如WebLogic的事務管理器)或者日志輸出中顯示的名字,?對于聲明式的事務設置,事務名字總是全限定名+"."+事務通知的類的方法名。比如BusinessService類的handlePayment(..)方法啟動了一個事務,事務的名稱是:

    com.foo.BusinessService.handlePayment


    from: http://blog.csdn.net/csh624366188/article/details/7661909

    總結

    以上是生活随笔為你收集整理的Java程序员从笨鸟到菜鸟之(八十)细谈Spring(九)spring+hibernate声明式事务管理详解的全部內容,希望文章能夠幫你解決所遇到的問題。

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

    主站蜘蛛池模板: 性一交一乱一色一视频麻豆 | 日韩欧美91 | 第一毛片 | 免费三级在线 | 免费簧片在线观看 | 午夜在线免费观看视频 | 在线观看中文字幕亚洲 | 日韩福利一区二区三区 | 亚洲精品国产suv | 最近中文字幕在线中文高清版 | 日本乱子伦xxxx | 欧美在线精品一区 | 亚洲激情久久 | 狠狠人妻久久久久久综合 | 久久精品高清视频 | 美女被揉胸视频 | 孕期1ⅴ1高h | 三上悠亚人妻中文字幕在线 | 捅肌肌| 亚洲精品综合在线 | 老司机午夜免费精品视频 | 日韩精品一区二区三区免费视频 | 秋葵视频污 | 久草热播 | 日本黄色高清视频 | 东北少妇高潮抽搐 | 91在线播| 黄色动漫软件 | 日韩欧美成人免费视频 | 免费在线观看毛片 | 日韩avav | 日韩影视一区二区三区 | av老司机久久 | 顶级毛茸茸aaahd极品 | 手机免费av片 | 国产精品亚洲视频 | 一区二区国产精品视频 | www.色天使| 午夜色影院| 色秀视频网 | 奇米影视久久 | 一级全黄少妇性色生活片 | 91精品网站| 国产毛片一区二区 | 国产一区二区三区精品视频 | 国产福利91| 91网址在线观看 | 亚洲精品日韩在线观看 | 天堂va蜜桃一区 | 亚洲欧美一区二区三区在线 | 在线观看成人动漫 | 国产又色又爽又黄 | 有码一区二区三区 | 日本一区不卡在线 | 国产又粗又长又黄的视频 | 波多野在线观看 | 日韩精品免费一区二区 | 天堂在线精品视频 | 日韩精品www| 国产第一页在线播放 | 久久日本精品字幕区二区 | 亚洲av永久无码精品国产精品 | 欧美日韩不卡在线 | 国产黄色一区二区 | 日韩一区二区三区精 | 日本少妇xxxxxx | 黄色激情在线观看 | 妹子色综合 | 一区二区美女视频 | 污污网站在线观看 | 蜜桃一二三区 | 91在线视频精品 | 天天想你免费观看完整版高清电影 | 亚洲第一在线 | 内射合集对白在线 | 精品一区二区三区四区五区六区 | 99精品视频在线观看 | 91网址在线| 日韩另类视频 | 久久bb| 影音先锋在线视频观看 | 日韩av男人天堂 | 西西午夜视频 | 好吊色网站 | 加勒比伊人 | 成人性毛片 | 亚洲视频一区 | 国产在线三区 | 国产亚洲精品久久 | missav | 免费高清av在线看 | 亚洲小说春色综合另类 | 国产一区二区在线免费 | 青苹果av| 成人黄色免费在线观看 | 毛片毛片女人毛片毛片 | 国产香蕉97碰碰碰视频在线观看 | 日本天天操 | 国产日韩欧美 | 日韩av免费网址 |