首頁  >  文章  >  php教程  >  Spring事務抽象

Spring事務抽象

高洛峰
高洛峰原創
2016-11-22 15:17:071210瀏覽

1    介紹Spring框架事務管理

全面的事務支援是使用Spring框架令人信服的原因。 Spring框架為事務管理提供一致性抽象,並擁有以下好處:

一致性程式設計模型跨不同交易APIs,例如,Java事務API(JTA)、JDBC、Hibernate、Java持久化API(JPA)和Java資料物件( JDO)。

支援聲明式事務管理。

比複雜事務APIs(例如,JTA)更簡單。

完美的與Spring的資料存取抽象整合。

2    Spring框架的事務支援模型的優點

傳統上,Java EE開發人員有兩種可選的事務管理方式:全域或本地事務,都有各自的限制。

2.1    全域事務

全域事務讓你能使用多個事務資源,通常是關聯式資料庫和訊息佇列。應用程式透過JTA管理全域事務,這是一個笨重的API。而且,JTA UserTransaction通常需要來自JNDI,這意味著你需要使用JNDI。顯然,使用全域事務會限制應用程式程式碼的重用,因為JTA通常只在應用程式伺服器環境有效。

以往,使用全域事務的首選方式是透過EJB CMT(容器管理事務):CMT是聲明式事務管理。 EJB CMT清除了相關事務的JNDI查找,不過EJB自己需要使用JNDI。它清除大多數(但不是全部)需要編寫Java程式碼控制交易。重要的缺點是,CMT捆綁JTA和應用程式伺服器環境。同時,它只有使用EJBs實現業務邏輯,或至少在事務EJB門面中時才有效。

2.2    本地事務

本地事務時特定資源,例如,事務關聯JDBC連線。本地事務易於使用,但有明顯缺點:它們不能跨越多個事務資源。例如,使用JDBC連線管理事務不能運行在全域JTA事務中。因為應用程式伺服器沒有負責事務管理,它不保證跨資源的正確性。另一個缺點是本地事務時入侵式程式設計模型。

2.3    Spring框架的一致性程式設計模型

Spring解決了全域和本地事務的缺點。它讓開發人員在任意環境使用一致性程式設計模型。開發人員只需編寫自己的程式碼,它能抽離不同環境中的不同的事務管理。 Spring框架提供聲明式和編程式事務管理。大多數使用者喜歡聲明式事務管理,這也是推薦的。

使用編程序事務管理,開發人員使用Spring框架事務抽象,能運作在任意底層事務之上。使用首選的聲明式模型,開發人員通常寫很少或不寫事務管理程式碼,因此,不依賴Spring框架交易API,或其它事務API。

3    瞭解Spring框架事務抽象

Spring事務抽象的關鍵是事務策略的概念。事務策略透過org.springframework.transaction.PlatformTransactionManager介面定義:

public interface PlatformTransaction actionException;

 

    void commit(TransactionStatus status) throws TransactionException;

 

    void rollback(TransactionStatus status) throws TransactionException;

}

這主要是服務提供介面(SPI),儘管它能在你的程式碼中使用程式設計模型。因為PlatformTransactionManager是一個接口,它很容易模擬(mocked)和存根(stubbed)。它不需要像JNDI一樣查找策略。 PlatformTransactionManager實作像Spring IoC容器中定義的其它物件一樣。這個好處讓Spring框架事務值得抽象,甚至是使用JTA時。事務代碼比直接使用JTA易於測試。

PlatformTransactionManager介面方法拋出的TransactionException是未偵測異常(即,繼承java.lang.RuntimeException)。事務失敗是致命性的。很少情況,應用程式程式碼能實際從事務失敗中恢復,應用程式開發人員能選擇擷取並處理TransactionException。優點在於開發人員不必強制這樣做。

getTransaction(..)方法依賴TransactionDefinition參數傳回TransactionStatus物件。傳回的TransactionStatus可以代表一個新事務,或者如果匹配事務在目前呼叫堆疊中存在則代表已存在的事務。其實就是後面這種情況,正如Java EE事務上下文,TransactionStatus關聯可執行的事務。

TransactionDefinition介面說明:

Isolation(事務隔離等級):交易隔離等級。例如,該事務是否能讀取其它的未提交事務?

Propagation(事務傳播):通常,所有程式碼執行在事務範圍將運行在事務中。然而,你有一個選項可以指定當事務上下文已存在時事務方法執行的行為。例如,程式碼能繼續運行在已存在的事務中(通常情況);或已存在的事務暫停,建立一個新事務。

事務逾時:此事務運作多久後失效,並透過底層事務自動回滾。

只讀狀態:當你的程式碼讀取但不修改資料時,可以使用唯讀交易。在某些情況下,只讀事務有利於最佳化,例如,當你使用Hibernate。

這些設定反應標準事務概念。底層這些概念是使用Spring框架或任意事務管理解決方案不可或缺的。

TransactionStatus介面提供交易程式碼簡單的方式控制可執行事務與查詢事務狀態:

public point();

 

void setRollbackOnly();

 

    boolean isRollbackOnly();

 

   

 

}

 無論你是否選擇Spring中的聲明式或編程式事務管理,定義正確的PlatformTransactionManager實作是不可或缺的。你通常透過依賴注入定義該實現。

PlatformTransactionManager通常需要知道工作的環境:JDBC、JTA、Hibernate等等。以下是定義本機PlatformTransactionManager的範例。

定義JDBC DataSource:

      ${jdbc.driverClassName}" />

    

    

    

   

PlatformTransactionManager org.springframework.jdbc.datasource.DataSourceTransactionManager">

   

 

透過使用JNDI和Spring的JtaTransactionManager來取得容器的DataSource:

      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

      schemaLocation="

        http://www.springframework.org/schema/beans

        http ://www.springframework.org /schema/jee

        Sharp "/>

   

    

        attributes>

    

 

    

        

    

 

   

        

     . />

        

        

        

預設情況下,只有拋出運行時異常或Error時導致Spring事務回滾。檢查異常不導致Spring交易回滾。

你能明確配置事務回滾的異常類型。

    

    for] NoProductInStockException"/>

        

    

你也能指定事務不會滾的異常類型:

        5.4    為不同的bean配置不同的事務語意

      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

      xmlns:aop="http://www.springframework.org/schema/  xmlns:aop="http://www.springjamework.org/schema/ ="http://www.springframework.org/schema/tx"

      xsi:schemaLocation="

        http work.org/ schema/beans/spring-beans.xsd

        http://www.springframework.org/schema/tx

          http:/ /www.springframework.org/schema/aop

        http://www.springframework.org/schema/aop/spring-aop.x   

        

        

 "/ >

    

 

    

    

            

        

            

      

5.5    設定

預設:

事務傳播設定是REQUIRED

事務隔離等級是DEFAULT

交易是讀取/寫入

事務超時時間任意RuntimeException異常觸發回滾,任意檢查Exception不觸發

你能改變這些預設值;嵌套在標籤中的標籤的各種屬性:

5.6    使用@Transactional

開啟註解管理事務:

 xml xsi="http://www.w3.org/2001/XMLSchema-instance"

      xmlns:aop="http://www.springframework.org/schema/aop"

="http://www.springframework.org/schema/aop"

    /www.springframework.org/schema/tx"

      xsi:schemaLocation="

        http://www.springframework.org/sche      http org/schema/beans/spring -beans.xsd

        http://www.springframework.org/schema/tx

        http ://www.springframework. org/schema/aop

        http://www.springframework.org/schema/aop/spring-aop.xsd">

 driven transaction-manager="txManager"/>

   

  ion

    

 

    

 

    Foo getFoo(String fooName);

 

    Foo getFoo(String fooName, String barName);

 🠎oo.

    void updateFoo(Foo foo);

}

@ Transactional設定:

@Transactional的多事務管理器:

public class TransactionalService {

 

   

 

    @Transactional("account")

    public void doSomething() { ... }

}Spring事務抽象

}

="  class="org .springframework.jdbc.datasource.DataSourceTransactionManager">

    ...

    

o . jdbc.datasource.DataSourceTransactionManager">

    ...

    

.

@Retention(RetentionPolicy.RUNTIME)

@Transactional("order")

public @interface OrderTx {

}

@Target({ElementType.METD, ElementType.METa. RUNTIME)

@Transactional("account")

public @interface AccountTx {

}

5.7    事務傳播

PROPAGATION_REQREDkAGATION。為每個方法建立一個邏輯事務範圍。每個邏輯事務範圍能單獨決定只回滾狀態,外部事務範圍邏輯獨立於內部事務範圍。當然,在標準的PROPAGATION_REQUIRED情況下,所有這些範圍將會對應相同的實體事務。因此,只回滾標記設定在內部交易範圍不影響外部事務發生的實際提交。

然而,在這種情況下,內部事務範圍設定為只回滾標記,外部事務沒有決定回滾,因此回滾是意想不到的。對應的UnexpectedRollbackException拋出。

PROPAGATION_REQUIRES_NEW

對比PROPAGATION_REQUIRED,PROPAGATION_REQUIRES_NEW使用完全獨立的交易。在這種情況下,底層實體事務是不同的,因此,能獨自提交或回滾,外部事務的回滾狀態不受內部事務的影響。

PROPAGATION_NESTED

使用一個能回滾到多個保存點的實體事務。這種回滾允許內部事務範圍觸發它的範圍回滾,外部事務能夠繼續物理事務,儘管一些操作已經回滾。此設定通常會對應到JDBC保存點,因此,只能用於JDBC資源事務。

6    編程序事務管理

Spring框架提供兩種編製事務管理:

使用TransactionTemplate(建議)

使用PlatformTransactionManager Template)相同的方式。

public class SimpleService implements Service {

 

    private final TransactionTemplate transactionTemplate;

    Assert.notNull(transactionManager, "The 'transactionManager' argument must not be null.");

        this.transactionTemplate = new TransactionTemplate(transactionManager);

    }

 transactionTemplate.execute(new TransactionCallback() {

            public Object doInTransaction(TransactionStatus status) {🠎  ();

                return resultOfUpdateOperation2();

       

    }

}

如果沒有回傳值,則使用TransactionCallbackWithoutResult類別:

transactionTemplate.execute(new TransactionCallbackWithoutResult() {tec void doInTransactionWithoutResult(TransactionStatus status) {

        updateOperation1();

      

在商業程式碼中回滾:

transactionTemplate.execute(new TransactionCallbackWithoutResult() {

 

    protected void doInTransactionWithoutResult(TransactionStatus status) {

        try {

          updateOperation2();

        } catch (SomeBusinessExeption ex)     }

    }

});

指定事務設定:

public class SimpleService implements Service {

 

    private final TransactionTemplate transaction遊戲Temp

        Assert.notNull(transactionManager, "The 'transactionManager' argument must not be null.");

        this.transactionTemplate = new TransactionTemplate(transactionManager);

     LATION_READ_UNCOMMITTED);

        this.transactionTemplate.setTimeout(30); // 30秒

   }

}

使用Spring XML配置TransactionTemplate:

 

   

6.2  

DefaultTransactionDefinition def = new DefaultTransactionDefinition();

def.setName("SomeTxName");

def.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQ​​

    / / 執行業務邏輯

} catch (MyException ex) {

    txManager.rollback(status);

    throw 程序還是聲明式管理事務?

如果你只有少量事務操作選擇編程序事務管理。

8    事務綁定事件

從Spring 4.2開始,監聽器事件可以綁定到事務階段。

@Componentpublic class MyComponent {

 

    @TransactionalEventListener

    public v. ...

    }

 

}

TransactionalEventListener註解暴露phase屬性允許客製化監聽事務階段。有效的階段是:BEFORE_COMMIT、AFTER_COMMIT(預設)、AFTER_ROLLBACK和AFTER_COMPLETION。 

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn