一区二区三区在线-一区二区三区亚洲视频-一区二区三区亚洲-一区二区三区午夜-一区二区三区四区在线视频-一区二区三区四区在线免费观看

服務器之家:專注于服務器技術及軟件下載分享
分類導航

PHP教程|ASP.NET教程|Java教程|ASP教程|編程技術|正則表達式|C/C++|IOS|C#|Swift|Android|VB|R語言|JavaScript|易語言|vb.net|

服務器之家 - 編程語言 - Java教程 - Spring的事務機制實例代碼

Spring的事務機制實例代碼

2021-04-02 13:33云中之歌 Java教程

這篇文章主要介紹了Spring的事務機制實例代碼,分享了相關代碼示例,小編覺得還是挺不錯的,具有一定借鑒價值,需要的朋友可以參考下

本文研究的主要是spring的事務機制的相關內容,具體如下。

java ee傳統事務機制

通常有兩種事務策略:全局事務和局部事務。全局事務可以跨多個事務性資源(即數據源,典型的是數據庫和消息隊列),通常都需要j2ee應用服務器的管理,其底層需要服務器的jta支持。而局部事務則與底層采用的持久化技術有關,如果底層直接使用jdbc,需要用connection對象來操事務。如果采用hibernate持久化技術,則需要使用session對象來操作事務。

通常的,使用jta事務,jdbc事務及hibernate事務的編程流程大致如下,

Spring的事務機制實例代碼

上圖也可以看出,采用傳統事務編程,程序代碼必須和具體的事務策略的api耦合,如果應用需要切換一種策略,意味著需要大幅修改代碼。但是如果使用spring事務的話,就不會有這個問題了。

spring事務機制

sring沒有提供任何事務支持,它只是負責包裝底層的事務,而在spring層面,對外提供統一的編程api。spring事務的核心是platformtransactionmanager接口,

platformtransactionmanager代表與具體類型無關的事務接口,可以代表任何事務,包括jdbc事務,hibernate事務,甚至是jta事務。

springa事務機制是一種典型的策略模式,platformtransactionmanager代表事務管理接口,但它并不知道到底如何管理事務,它只要求事務管理提供開始事務gettransaction(),提交事務commit()和回滾事務rollback()這三個方法,但具體如何實現則交給其實現類完成。編程人員只需要在配置文件中根據具體需要使用的事務類型做配置,spring底層就自動會使用具體的事務實現類進行事務操作,而對于程序員來說,完全不需要關心底層過程,只需要面向platformtransactionmanager接口進行編程即可。platformtransactionmanager接口中提供了如下方法:gettransaction(..), commit(); rollback(); 這些都是與平臺無關的事務操作。

gettransaction()的完整寫法為 transactionstatus gettransaction(transactiondefinition definiton)

這個方法用來返回一個事務對象,其中的參數transactiondefinition 則可以為事務對象指定各種屬性,通常可以指定 事務的隔離屬性, 傳播屬性, 超時,只讀 這幾個屬性。

spring具體的事務管理需要在配置文件中配置好platformtransactionmanager,下面是不同類型的事務對應的spring配置。

jdbc數據源的局部事務管理器的配置如下,

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<!-- 定義數據源bean,使用c3p0數據源實現,并注入數據源的必要信息 -->
  <bean id="datasource" class="com.mchange.v2.c3p0.combopooleddatasrouce"
    destroy-method="close"
    p:driverclass="com.mysql.jdbc.driver"
    p:jdbcurl="jdbc:mysql://localhost/test"
    p:user="root"
    p:password=""
    p:maxpoolsize="40"
    p:minpoolsize="2"
    p:initialpoolsize="2"
    p:maxidletime="30" />
  <!-- 配置jdbc數據源的局部數據管理器,使用datasourcetransactionmanager類 -->
  <bean id="transactionmanager"
    class="org.springframework.jdbc.datasource.datasourcetransactionmanager"
    p:datasource-ref="datasource" />

容器管理的jta全局事務管理器的配置如下,

?
1
2
3
4
5
<bean id="datasource" class="org.springframework.jndi.jndiobjectfactorybean"
  p:jndiname="jdbc/jpetstore" />
<!-- 使用jtatransactionmanager類, 該類實現了platformtransactionmanager接口 -->
<!-- 使用jta全局事務,spring容器可以自行從java ee服務器中獲取事務性資源,無需依賴注入 -->
<bean id="transactionmanager" class="org.springframework.transaction.jta.jtatransactionmanager" />

對于jta全局事務,只需要指定事務管理器的實現類jtatransactionmanager即可,spring容器會自行從j2ee服務器獲取數據源,無需顯式注入進事務管理器。

基于hibernate持久化技術的spring局部事務配置如下,

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
<!-- 定義數據源bean,使用c3p0數據源實現,并注入數據源的必要信息 -->
  <bean id="datasource" class="com.mchange.v2.c3p0.combopooleddatasrouce"
    destroy-method="close"
    p:driverclass="com.mysql.jdbc.driver"
    p:jdbcurl="jdbc:mysql://localhost/test"
    p:user="root"
    p:password=""
    p:maxpoolsize="40"
    p:minpoolsize="2"
    p:initialpoolsize="2"
    p:maxidletime="30" />
  <!-- 定義hibernate的sessionfactory, sessionfactory需要依賴數據源,注入datasource -->
  <bean id="sessionfactory"
    class="org.springframework.orm.hibernate4.localsessionfactorybean"
    p:datasource-ref="datasource">
    <!-- annotatedclasses用來列出全部持久化類 --> 
    <property name="annotatedclasses">
      <list>
        <!-- 以下用來列出所有po類 -->
        <value>com.entity.user</value>
      </list>
    </property>
    <!-- 定義hibernate的sessionfactory屬性 -->
    <property name="hibernateproperties">
      <props>
        <!-- 指定hibernate的連接方言 -->
        <prop key="hibernate.dialect">org.hibernate.dialect.mysql5innodbdialect</prop>
        <!-- 是否根據hibernate映射表創建數據表 -->
        <prop key="hibernate.hbm2ddl.auto">update</prop>
      </props>
    </property>
  </bean>
  <!-- 配置hibernate的局部數據管理器,使用hibernatetransactionmanager類 -->
  <!-- 該類是platformtransactionmanager接口針對hibernate的特定實現 -->
  <!-- 配置hibernatetransactionmanager需要注入sessionfactory -->
  <bean id="transactionmanager"
    class="org.springframework.orm.hibernate4.hibernatetransactionmanager"
    p:sessionfactory-ref="sessionfactory" />

spring事務如果采用hibernate策略,一般需要配置三點:數據源, sessionfactory, 事務管理器。

如果底層采用hibernate持久層技術,而事務采用jta全局事務時,配置如下,

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
<!-- 配置jta數據源-->
  <bean id="datasource" class="org.springframework.jndi.jndiobjectfactorybean"
    p:jndiname="jdbc/jpetstore" />
  <!-- 定義hibernate的sessionfactory, sessionfactory需要依賴數據源,注入datasource -->
  <bean id="sessionfactory"
    class="org.springframework.orm.hibernate4.localsessionfactorybean"
    p:datasource-ref="datasource">
    <!-- annotatedclasses用來列出全部持久化類 --> 
    <property name="annotatedclasses">
      <list>
        <!-- 以下用來列出所有po類 -->
        <value>com.entity.user</value>
      </list>
    </property>
    <!-- 定義hibernate的sessionfactory屬性 -->
    <property name="hibernateproperties">
      <props>
        <!-- 指定hibernate的連接方言 -->
        <prop key="hibernate.dialect">org.hibernate.dialect.mysql5innodbdialect</prop>
        <!-- 是否根據hibernate映射表創建數據表 -->
        <prop key="hibernate.hbm2ddl.auto">update</prop>
      </props>
    </property>
  </bean>
  <!-- 使用jtatransactionmanager類,該類是platformtransactionmanager接口的實現類 -->
  <!-- 針對全局事務管理的特定實現 -->
  <bean id="transactionmanager" class="org.springframework.transaction.jta.jtatransactionmanager" />

這與前面的基于hibernate的spring事務比起來,就是將數據源換成了jndi數據源, 將事務管理器換成了jtatransactionmanager.

對于jta全局事務,因為需要底層應用服務器的支持,而不同應用服務器所提供的jta全局事務可能存在細節上的差異,因此實際配置全局事務管理器時可能需要使用jtatransactionmanager的子類,例如oracle的javaee應用服務器提供的oc4jjtatransactionmanager,oracle為weblogic提供的weblogicjtatransactionmanager, ibm為websphere提供的websphereuowtransactionmanager等。

從上面各種事務類型的spring配置可以看出,當應用程序采用spring事務管理時,應用程序無需與具體的事務api耦合,應用程序只需要面向platormtransactionmanager接口編程即可,applicationcontext會根據配置文件選擇合適的事務策略實現類(即platormtransactionmanager的實現類)。

那么在具體在spring中如何進行事務控制編程呢,通常有兩種方式,

編程式事務管理:就是直接在代碼中使用platormtransactionmanager提供的三個抽象方法進行事務流程控制。也可以在spring容器中獲取platormtransactionmanager類型的bean,該bean總是platormtransactionmanager的具體實現類的實例,具體的實現類則由applicationcontext按照策略模式進行選擇,編程人員無需關心,只需要面向接口編程即可。

聲明式事務管理:這種方式不需要講事務控制流程寫入代碼中,而是通過aop的方式,完全由配置文件完成事務的織入。即xml配置文件可以為業務組件配置事務代理,事務代理為業務組件提供事務控制。現在這種方式是最好的,源碼侵入性最低。

使用聲明式事務管理-使用xml schema配置事務策略

當使用聲明式事務時,只需要寫好配置文件,配置需要事務控制的組件種類,業務組件就會在aop機制下被織入事務控制,而編程人員不需要寫任何事務管理代碼,可以專注于業務組件的開發。因此通常都推薦使用聲明式事務管理。

spring的xml schema方式提供了簡潔的事務配置策略,通過命名空間 <tx:advice> 來配置一個事務增強處理,其中可以指定事務的各種屬性(例如隔離屬性, 傳播屬性, 超時,只讀屬性等等),然后通過<aop:config>標簽可以將事務的增強與aop的切入點(即bean的執行方法)進行綁定,從而實現對bean的方法織入事務操作。下面是一個簡單的例子,配置一個newsdaoimpl bean進行數據操作,使用c3p0數據源,spring的jdbc事務管理器,在<tx:advice對事務設置屬性。

完整的spring配置如下,

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
<?xml version="1.0" encoding="utf-8"?>
<beans xmlns:xsi="http://www.w3.org/2001/xmlschema-instance"
  xmlns="http://www.springframework.org/schema/beans"
  xmlns:p="http://www.springframework.org/schema/p"
  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-4.0.xsd
  http://www.springframework.org/schema/aop
  http://www.springframework.org/schema/aop/spring-aop-4.0.xsd
  http://www.springframework.org/schema/tx
  http://www.springframework.org/schema/tx/spring-tx-4.0.xsd">
  <!-- 定義數據源bean,使用c3p0數據源實現,并注入數據源的必要信息 -->
  <bean id="datasource" class="com.mchange.v2.c3p0.combopooleddatasource"
    destroy-method="close"
    p:driverclass="com.mysql.jdbc.driver"
    p:jdbcurl="jdbc:mysql://localhost/test?useunicode=true&characterencoding=utf-8"
    p:user="root"
    p:password=""
    p:maxpoolsize="40"
    p:minpoolsize="2"
    p:initialpoolsize="2"
    p:maxidletime="30" />
  <!-- 配置jdbc數據源的局部數據管理器,使用datasourcetransactionmanager類 -->
  <bean id="transactionmanager"
    class="org.springframework.jdbc.datasource.datasourcetransactionmanager"
    p:datasource-ref="datasource" />
  
  <!-- 配置一個業務邏輯bean -->
  <bean id="newsdao" class="com.dao.impl.newsdaoimpl" p:ds-ref="datasource" />
  <!-- 配置事務增強處理, 指定事務管理器 -->
  <tx:advice id="txadvice"
    transaction-manager="transactionmanager">
    <!-- 用于配置詳細的事務定義 -->
    <tx:attributes>
      <!-- 所有以get開頭的方法都是只讀的 -->
      <tx:method name="get*" read-only="true" />
      <!-- 其他方法默認都適用事務,指定超時5秒 -->
      <tx:method name="*" isolation="default" propagation="required" timeout="5" />
    </tx:attributes>
  </tx:advice>
  <aop:config>
    <!-- 配置一個切入點,匹配impl包下所有以impl結尾的類里的所有方法的執行 -->
    <aop:pointcut expression="execution(* com.dao.impl.*impl.*(..))" id="mypointcut" />
    <!-- 將切入點mypointcut和增強txadvice綁定-->
    <aop:advisor advice-ref="txadvice" pointcut-ref="mypointcut" />
    <!-- 再配置一個切入點,匹配impl包下所有以abc開頭類里的所有方法的執行 -->
  </aop:config>
</beans>

newsdaoimpl代碼中,則是插入重復數據到表中,

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
package com.dao.impl;
import javax.sql.datasource;
import org.springframework.jdbc.core.jdbctemplate;
import com.dao.newsdao;
public class newsdaoimpl implements newsdao {
    private datasource ds;
    public void setds(datasource ds) {
        this.ds = ds;
    }
    @override
      public void insert(string title, string content) {
        //c3p0數據池的用法
        jdbctemplate jt = new jdbctemplate(ds);
        jt.update("insert into news_inf" + " values(100,?,?)", title, content);
        jt.update("insert into news_inf" + " values(100,?,?)", title, content);
        //如果沒有事務控制,則第一條記錄可以被插入
        //如果增加事務控制,將發現第一條記錄也插不進去
    }
}

下面是測試方法,

?
1
2
3
4
5
6
7
public static void test3() {
    applicationcontext ctx = new classpathxmlapplicationcontext("beans4jdbc.xml");
    //獲取事務代理bean
    newsdao dao = (newsdao)ctx.getbean("newsdao", newsdao.class);
    dao.insert("java編程核心思想", "輕量級java ee開發");
    system.out.println("執行完畢");
  }

執行測試方法會發現拋出異常(因為有重復數據),而又因為事務控制,數據庫中講不會有數據插入。

可以看到上面例子中,通常對于xml schema的配置中,其實就是對一個普通的bean做了aop配置,織入一個advice增強,而advice增強中則配置一個事務管理器,事務管理器又依賴數據源。

對于<aop:advisor>中,將advice和切入點的綁定,而在spring底層是由bean后處理器完成(例如beannameautoproxycreator, defaultadvisorautoproxycreator),其本質就是動態代理。

另外,在<tx:advice>配置增強中,還可以為事務指定再遇到特定異常時,進行強制rollback和強制不rollback,即rollback-for="xxxexception", no-rollback-for="xxxexception"

使用@transactionl

除了使用xml schema的方法之外,也可以直接在方法上添加@transaction注解,使這個方法具有事務屬性。 在@transaction中可以為事務配置各種屬性(例如隔離屬性, 傳播屬性, 超時,只讀屬性等等),此外,還需要在在xml配置中加入<tx:annotation-triven配置表明spring會根據注解來配置事務代理,這樣,事務的屬性配置和aop切入配置就可以只通過一步(直接通過注解配置在方法名上)完成了。

?
1
<tx:annotation-driven transaction-manager="transactionmanager" />

newsdaoimpl.

?
1
2
3
@transactional(propagation=propagation.required, isolation=isolation.default, timeout=5)
@override
public void insert(string title, string content) {

總結

以上就是本文關于spring的事務機制實例代碼的全部內容,希望對大家有所幫助。感興趣的朋友可以繼續參閱本站其他相關專題,如有不足之處,歡迎留言指出。感謝朋友們對本站的支持!

原文鏈接:http://www.cnblogs.com/fysola/p/6384399.html

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 亚洲风情无码免费视频 | 门房秦大爷在线阅读 | 北条麻妃一区 | 香蕉视频在线观看网址 | 日本人成年视频在线观看 | 国产精品永久免费10000 | 色悠久久久久综合网小说 | 耽美双性 | a亚洲天堂| 91网站入口| 欧美一区二区三区精品国产 | 色综色| 国产午夜精品久久久久小说 | 高清毛片一区二区三区 | 国产精品久久久久久久午夜片 | 国产欧美综合一区二区 | 欧美在线一级片 | a毛片免费全部在线播放毛 a级在线看 | 风间由美被义子中文字幕 | 边摸边吃奶玩乳尖视频 | 日本伊人色综合网 | 韩国成人毛片aaa黄 含羞草国产亚洲精品岁国产精品 | 2020年精品国产午夜福利在线 | 99久久www免费 | 和两个男人玩3p好爽视频 | 精品国产剧情在线观看 | 久久中文字幕综合不卡一二区 | 四虎在线最新地址公告 | 亚洲欧美一区二区三区在饯 | 亚洲天堂男人的天堂 | 国产精品久久久久久影视 | 九九精品免视频国产成人 | 国产色拍 | 放荡警察巨r麻麻出轨小说 范冰冰特黄xx大片 饭冈加奈子在线播放观看 法国老妇性xx在线播放 | 99在线在线视频免费视频观看 | 互换身体全集免费观看 | 调教女秘书| 亚洲成a人片777777久久 | 无人在线视频高清免费观看动漫 | blacked黑人| 男女男精品视频 |