日韩av黄I国产麻豆传媒I国产91av视频在线观看I日韩一区二区三区在线看I美女国产在线I麻豆视频国产在线观看I成人黄色短片

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 >

spring transaction源码分析--事务架构

發(fā)布時(shí)間:2023/10/11 125 老码农
生活随笔 收集整理的這篇文章主要介紹了 spring transaction源码分析--事务架构 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

1. 引言  事務(wù)特性

事務(wù)是并發(fā)控制的單元,是用戶定義的一個(gè)操作序列。這些操作要么都做,要么都不做,是一個(gè)不可分割的工作單位。通過事務(wù)將邏輯相關(guān)的一組操作綁定在一起,以便服務(wù)器 保持?jǐn)?shù)據(jù)的完整性。事務(wù)通常是以begin transaction開始,以commit或rollback結(jié)束。Commint表示提交,即提交事務(wù)的所有操作。具體地說就是將事務(wù)中所有對(duì)數(shù)據(jù)的更新寫回到磁盤上的物理數(shù)據(jù)庫(kù)中去,事務(wù)正常結(jié)束。Rollback表示回滾,即在事務(wù)運(yùn)行的過程中發(fā)生了某種故障,事務(wù)不能繼續(xù)進(jìn)行,系統(tǒng)將事務(wù)中對(duì)數(shù)據(jù)庫(kù)的所有已完成的操作全部撤消,滾回到事務(wù)開始的狀態(tài)。

  原子性(Atomic) 對(duì)數(shù)據(jù)的修改要么全部執(zhí)行,要么全部不執(zhí)行。

  一致性(Consistent) 在事務(wù)執(zhí)行前后,數(shù)據(jù)狀態(tài)保持一致性。

  隔離性(Isolated) 一個(gè)事務(wù)的處理不能影響另一個(gè)事務(wù)的處理。

  持續(xù)性(Durable) 事務(wù)處理結(jié)束,其效果在數(shù)據(jù)庫(kù)中持久化。

 2. Java事務(wù)的類型

Java事務(wù)的類型有三種:JDBC事務(wù)、JTA(Java Transaction API)事務(wù)、容器事務(wù)。

1、JDBC事務(wù)

JDBC 事務(wù)是用 Connection 對(duì)象控制的。JDBC Connection 接口( java.sql.Connection )提供了兩種事務(wù)模式:自動(dòng)提交和手工提交。 java.sql.Connection 提供了以下控制事務(wù)的方法:

  public void setAutoCommit(boolean)
  public boolean getAutoCommit()
  public void commit()
  public void rollback()

使用 JDBC 事務(wù)界定時(shí),您可以將多個(gè) SQL 語句結(jié)合到一個(gè)事務(wù)中。JDBC 事務(wù)的一個(gè)缺點(diǎn)是事務(wù)的范圍局限于一個(gè)數(shù)據(jù)庫(kù)連接。一個(gè) JDBC 事務(wù)不能跨越多個(gè)數(shù)據(jù)庫(kù)。

2、JTA(Java Transaction API)事務(wù)

JTA是一種高層的,與實(shí)現(xiàn)無關(guān)的,與協(xié)議無關(guān)的API,應(yīng)用程序和應(yīng)用服務(wù)器可以使用JTA來訪問事務(wù)。

JTA允許應(yīng)用程序執(zhí)行分布式事務(wù)處理——在兩個(gè)或多個(gè)網(wǎng)絡(luò)計(jì)算機(jī)資源上訪問并且更新數(shù)據(jù),這些數(shù)據(jù)可以分布在多個(gè)數(shù)據(jù)庫(kù)上。JDBC驅(qū)動(dòng)程序的JTA支持極大地增強(qiáng)了數(shù)據(jù)訪問能力。

如果計(jì)劃用 JTA 界定事務(wù),那么就需要有一個(gè)實(shí)現(xiàn) javax.sql.XADataSource 、 javax.sql.XAConnection 和 javax.sql.XAResource 接口的 JDBC 驅(qū)動(dòng)程序。一個(gè)實(shí)現(xiàn)了這些接口的驅(qū)動(dòng)程序?qū)⒖梢詤⑴c JTA 事務(wù)。一個(gè) XADataSource 對(duì)象就是一個(gè) XAConnection 對(duì)象的工廠。 XAConnection s 是參與 JTA 事務(wù)的 JDBC 連接。

您將需要用應(yīng)用服務(wù)器的管理工具設(shè)置 XADataSource .從應(yīng)用服務(wù)器和 JDBC 驅(qū)動(dòng)程序的文檔中可以了解到相關(guān)的指導(dǎo)。

J2EE應(yīng)用程序用 JNDI 查詢數(shù)據(jù)源。一旦應(yīng)用程序找到了數(shù)據(jù)源對(duì)象,它就調(diào)用 javax.sql.DataSource.getConnection() 以獲得到數(shù)據(jù)庫(kù)的連接。

XA 連接與非 XA 連接不同。一定要記住 XA 連接參與了 JTA 事務(wù)。這意味著 XA 連接不支持 JDBC 的自動(dòng)提交功能。同時(shí),應(yīng)用程序一定不要對(duì) XA 連接調(diào)用 java.sql.Connection.commit() 或者 java.sql.Connection.rollback() .

相反,應(yīng)用程序應(yīng)該使用 UserTransaction.begin()、 UserTransaction.commit() 和 serTransaction.rollback() .

3、容器事務(wù)

容器事務(wù)主要是J2EE應(yīng)用服務(wù)器提供的,容器事務(wù)大多是基于JTA完成,這是一個(gè)基于JNDI的,相當(dāng)復(fù)雜的API實(shí)現(xiàn)。相對(duì)編碼實(shí)現(xiàn)JTA事務(wù)管理, 我們可以通過EJB容器提供的容器事務(wù)管理機(jī)制(CMT)完成同一個(gè)功能,這項(xiàng)功能由J2EE應(yīng)用服務(wù)器提供。這使得我們可以簡(jiǎn)單的指定將哪個(gè)方法加入事 務(wù),一旦指定,容器將負(fù)責(zé)事務(wù)管理任務(wù)。這是我們土建的解決方式,因?yàn)橥ㄟ^這種方式我們可以將事務(wù)代碼排除在邏輯編碼之外,同時(shí)將所有困難交給J2EE容 器去解決。使用EJB CMT的另外一個(gè)好處就是程序員無需關(guān)心JTA API的編碼,不過,理論上我們必須使用EJB.

4、三種Java事務(wù)差異

  JDBC事務(wù)控制的局限性在一個(gè)數(shù)據(jù)庫(kù)連接內(nèi),但是其使用簡(jiǎn)單。

   JTA事務(wù)的功能強(qiáng)大,事務(wù)可以跨越多個(gè)數(shù)據(jù)庫(kù)或多個(gè)DAO,使用也比較復(fù)雜。

  容器事務(wù),主要指的是J2EE應(yīng)用服務(wù)器提供的事務(wù)管理,局限于EJB應(yīng)用使用。

5、應(yīng)用場(chǎng)景

Java事務(wù)控制是構(gòu)建J2EE應(yīng)用不可缺少的一部分,合理選擇應(yīng)用何種事務(wù)對(duì)整個(gè)應(yīng)用系統(tǒng)來說至關(guān)重要。一般說來,在單個(gè)JDBC 連接連接的情況下可以選擇JDBC事務(wù),在跨多個(gè)連接或者數(shù)據(jù)庫(kù)情況下,需要選擇使用JTA事務(wù),如果用到了EJB,則可以考慮使用EJB容器事務(wù)

3. spring事務(wù)實(shí)現(xiàn)源碼分析

 3.1 dao模塊
    
dao模塊定義了數(shù)據(jù)庫(kù)層的各種異常,其中異常的結(jié)構(gòu)已經(jīng)在spring-jdbc模塊中介紹過了,在這里主要是dao的支持和異常的轉(zhuǎn)譯,其數(shù)據(jù)庫(kù)支持和轉(zhuǎn)譯結(jié)構(gòu)如下所示:

dao 支持
提供了對(duì)hibernate、jdbc,cci的支持。我們都想到熟悉,對(duì)cci可能有些陌生,下面的章節(jié)會(huì)講到。
dao異常轉(zhuǎn)譯
PersistenceExceptionTranslationPostProcessor:自動(dòng)將標(biāo)示為@repository的bean的持久化異常進(jìn)行轉(zhuǎn)譯。它增加一個(gè)PersistenceExceptionTranslationAdvisor來代理相應(yīng)的已經(jīng)存在的aop代理或者實(shí)現(xiàn)了目標(biāo)接口的新產(chǎn)生的代理。它將本地資源異常轉(zhuǎn)換為spring的DataAccessException及其子類上。
PersistenceExceptionTranslationAdvisor是一個(gè)spring aop的異常轉(zhuǎn)譯類,它應(yīng)用到respository層或者dao層。它基于給定的PersistenceExceptionTranslator來將本地持久化異常轉(zhuǎn)換為spring的DataAccessException族。  PersistenceExceptionTranslationInterceptor:一個(gè)aop 方法攔截器(MethodInterceptor).提供基于PersistenceExceptionTranslator的異常轉(zhuǎn)換,它是PersistenceExceptionTranslator的代理,將運(yùn)行時(shí)拋出的異常轉(zhuǎn)換為spring 的DataAccessException族。 PersistenceExceptionTranslator spring集成其它數(shù)據(jù)獲取技術(shù)(如jpa、toplink、jdo、hibernate等)拋出運(yùn)行時(shí)異常的接口。 3.2 jca模塊
   1. cci模塊
J2EE提供JCA(Java Connector Architecture)規(guī)范來標(biāo)準(zhǔn)化對(duì)EIS(Enterprise Information System)的訪問。這個(gè)規(guī)范被分為幾個(gè)不同的部分: 

  SPI(Service provider interfaces)是連接器提供者(connector provider)必須實(shí)現(xiàn)的接口。 這些接口組成了一個(gè)能被部署在J2EE應(yīng)用服務(wù)器上的資源適配器(resource adapter)。 在這種情況下,由服務(wù)器來管理連接池(connection pooling)、事務(wù)和安全(托管模式(managed mode))。 應(yīng)用服務(wù)器還負(fù)責(zé)管理客戶端應(yīng)用程序之外所擁有的配置。連接器(connector)同樣能在脫離應(yīng)用服務(wù)器的情況下使用;在這種情況下,應(yīng)用程序必須直接對(duì)它進(jìn)行配置(非托管模式(non-managed mode))。 

  CCI (Common Client Interface)是應(yīng)用程序用來與連接器交互并與EIS通信的接口。同樣還為本地事務(wù)劃界提供了API。 

  Spring對(duì)CCI的支持,目的是為了提供以典型的Spring方式來訪問CCI連接器的類,并有效地使用Spring的通用資源和事務(wù)管理工具。 

注意: 
連接器的客戶端不必總是使用CCI。 某些連接器暴露它們自己的API,只提供JCA資源適配器(resource adapter) 以使用J2EE容器的某些系統(tǒng)契約(system contracts)(連接池(connection pooling),全局事務(wù)(global transactions),安全(security))。 Spring并沒有為這類連接器特有(connector-specific)的API提供特殊的支持。
 2. context模塊
ResourceAdapterApplicationContext:一個(gè)jca ResourceAdapter的applicationContext實(shí)現(xiàn),需要于jca的bootstrapContext一同初始化,最后傳遞到實(shí)現(xiàn)了BootstrapContextAware的spring 受管理bean。
    @Override
protected void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
beanFactory.addBeanPostProcessor(new BootstrapContextAwareProcessor(this.bootstrapContext));
beanFactory.ignoreDependencyInterface(BootstrapContextAware.class);
beanFactory.registerResolvableDependency(BootstrapContext.class, this.bootstrapContext); // JCA WorkManager resolved lazily - may not be available.
beanFactory.registerResolvableDependency(WorkManager.class, new ObjectFactory<WorkManager>() {
@Override
public WorkManager getObject() {
return bootstrapContext.getWorkManager();
}
});
}
BootstrapContextAwareProcessor:傳遞BootstrapContext到實(shí)現(xiàn)了BootStrapContextAware接口的spring bean。它在內(nèi)部bean factory中自動(dòng)注冊(cè)。
BootstrapContextAware:需要通知BootStrapContext的實(shí)現(xiàn)類。
BootstrapContext:提供一種機(jī)制,這種機(jī)制將一個(gè)Bootstrap的上下文傳遞到一個(gè)資源適配器實(shí)例。
3.endpoint模塊
AbstractMessageEndpointFactory:實(shí)現(xiàn)了jca 1.5、1.6、1.7版本的javax.resource.spi.endpoint.MessageEndpointFactory接口,它提供了事務(wù)管理能力。
GenericMessageEndpointFactory實(shí)現(xiàn)了抽象方法,對(duì)任意類型的消息監(jiān)聽對(duì)象(javax.jms.MessageListener)或者javax.resource.cci.MessageListener對(duì)象提供了事務(wù)管理的能力。
GenericMessageEndpointManager管理類,對(duì)上述方法進(jìn)行管理。
4.support模塊
LocalConnectionFactoryBean:創(chuàng)建一個(gè)本地JCA連接工廠。
ResourceAdapterFactoryBean :使用BootStrapContext啟動(dòng)一個(gè)jca 1.5指定的ResouceAdapter。
5. work模塊
結(jié)構(gòu)如下:

WorkManager提供了提交Work(Work繼承了Runnable)可執(zhí)行實(shí)例的便利類。
3.3 transaction模塊

spring事務(wù)架構(gòu)

3.3.1 事務(wù)管理PlatformTransactionManager的架構(gòu)

如下圖所示:

PlatformTransactionManager:spring事務(wù)的核心接口。

3.3.2 事務(wù)定義TransactionDefinition的架構(gòu)

如下圖所示:

TransactionDefinition:定義spring容器事務(wù)屬性的接口。

包括事務(wù)傳播行為類型和事務(wù)隔離級(jí)別:

事務(wù)傳播行為類型

事務(wù)傳播行為類型

說明

PROPAGATION_REQUIRED

如果當(dāng)前沒有事務(wù),就新建一個(gè)事務(wù),如果已經(jīng)存在一個(gè)事務(wù)中,加入到這個(gè)事務(wù)中。這是最常見的選擇。

PROPAGATION_SUPPORTS

支持當(dāng)前事務(wù),如果當(dāng)前沒有事務(wù),就以非事務(wù)方式執(zhí)行。

PROPAGATION_MANDATORY

使用當(dāng)前的事務(wù),如果當(dāng)前沒有事務(wù),就拋出異常。

PROPAGATION_REQUIRES_NEW

新建事務(wù),如果當(dāng)前存在事務(wù),把當(dāng)前事務(wù)掛起。

PROPAGATION_NOT_SUPPORTED

以非事務(wù)方式執(zhí)行操作,如果當(dāng)前存在事務(wù),就把當(dāng)前事務(wù)掛起。

PROPAGATION_NEVER

以非事務(wù)方式執(zhí)行,如果當(dāng)前存在事務(wù),則拋出異常。

PROPAGATION_NESTED

如果當(dāng)前存在事務(wù),則在嵌套事務(wù)內(nèi)執(zhí)行。如果當(dāng)前沒有事務(wù),則執(zhí)行與PROPAGATION_REQUIRED類似的操作。

當(dāng)使用PROPAGATION_NESTED時(shí),底層的數(shù)據(jù)源必須基于JDBC 3.0,并且實(shí)現(xiàn)者需要支持保存點(diǎn)事務(wù)機(jī)制。

隔離級(jí)別:

為了避免上面出現(xiàn)幾種情況在標(biāo)準(zhǔn)SQL規(guī)范中定義了4個(gè)事務(wù)隔離級(jí)別,不同隔離級(jí)別對(duì)事務(wù)處理不同

  1. 未授權(quán)讀取(Read Uncommitted):也稱未提交讀。防止更新丟失(這不對(duì)應(yīng)一級(jí)鎖嗎),如果一個(gè)事務(wù)已經(jīng)開始寫數(shù)據(jù)則另外一個(gè)數(shù)據(jù)則不允許同時(shí)進(jìn)行寫操作但允許其他事務(wù)讀此行數(shù)據(jù)。該隔離級(jí)別可以通過“排他寫鎖”實(shí)現(xiàn)。事務(wù)隔離的最低級(jí)別,僅可保證不讀取物理損壞的數(shù)據(jù)。與READ COMMITTED 隔離級(jí)相反,它允許讀取已經(jīng)被其它用戶修改但尚未提交確定的數(shù)據(jù)。

  2. 授權(quán)讀取(Read Committed):也稱提交讀。1之上防止臟讀取(這不對(duì)應(yīng)二級(jí)鎖嗎)。這可以通過“瞬間共享讀鎖”和“排他寫鎖”實(shí)現(xiàn),讀取數(shù)據(jù)的事務(wù)允許其他事務(wù)繼續(xù)訪問該行數(shù)據(jù),但是未提交寫事務(wù)將會(huì)禁止其他事務(wù)訪問該行。SQL Server 默認(rèn)的級(jí)別。在此隔離級(jí)下,SELECT 命令不會(huì)返回尚未提交(Committed) 的數(shù)據(jù),也不能返回臟數(shù)據(jù)。

  3. 可重復(fù)讀取(Repeatable Read):2之上防止不可重復(fù)讀取(這不對(duì)應(yīng)三級(jí)鎖嗎)。但是有時(shí)可能出現(xiàn)幻影數(shù)據(jù),這可以通過“共享讀鎖”和“排他寫鎖”實(shí)現(xiàn),讀取數(shù)據(jù)事務(wù)將會(huì)禁止寫事務(wù)(但允許讀事務(wù)),寫事務(wù)則禁止任何其他事務(wù)。在此隔離級(jí)下,用SELECT 命令讀取的數(shù)據(jù)在整個(gè)命令執(zhí)行過程中不會(huì)被更改。此選項(xiàng)會(huì)影響系統(tǒng)的效能,非必要情況最好不用此隔離級(jí)。

  三級(jí)封鎖協(xié)議并不能阻止幻讀,修改的不能再被讀取,但是新增(刪除)的記錄數(shù)可以統(tǒng)計(jì)。

  4. 串行(Serializable):也稱可串行讀(這不對(duì)應(yīng)兩段鎖嗎)。提供嚴(yán)格的事務(wù)隔離,它要求事務(wù)序列化執(zhí)行,事務(wù)只能一個(gè)接著一個(gè)地執(zhí)行,但不能并發(fā)執(zhí)行。如果僅僅通過 “行級(jí)鎖”是無法實(shí)現(xiàn)事務(wù)序列化的,必須通過其他機(jī)制保證新插入的數(shù)據(jù)不會(huì)被剛執(zhí)行查詢操作事務(wù)訪問到。事務(wù)隔離的最高級(jí)別,事務(wù)之間完全隔離。如果事務(wù)在可串行讀隔離級(jí)別上運(yùn)行,則可以保證任何并發(fā)重疊事務(wù)均是串行的。

  LU丟失更新 DR臟讀 NRR非重復(fù)讀SLU二類丟失更新 PR幻像讀

為了解決與“多個(gè)線程請(qǐng)求相同數(shù)據(jù)”相關(guān)的問題,事務(wù)之間用鎖相互隔開。多數(shù)主流的數(shù)據(jù)庫(kù)支持不同類型的鎖;因此,JDBC API 支持不同類型的事務(wù),它們由 Connection 對(duì)象指派或確定。 
        為了在性能與一致性之間尋求平衡才出現(xiàn)了上面的幾種級(jí)別。事務(wù)保護(hù)的級(jí)別越高,性能損失就越大。
        假定您的數(shù)據(jù)庫(kù)和 JDBC 驅(qū)動(dòng)程序支持這個(gè)特性,則給定一個(gè) Connection 對(duì)象,您可以明確地設(shè)置想要的事務(wù)級(jí)別:
        conn.setTransactionLevel(TRANSACTION_SERIALIZABLE) ;
        可以通過下面的方法確定當(dāng)前事務(wù)的級(jí)別:
            int level = conn.getTransactionIsolation();

SavepointManager:管理事務(wù)savepoint的編程式API接口。

JDBC定義了SavePoint接口,提供在一個(gè)更細(xì)粒度的事務(wù)控制機(jī)制。當(dāng)設(shè)置了一個(gè)保存點(diǎn)后,可以rollback到該保存點(diǎn)處的狀態(tài),而不是rollback整個(gè)事務(wù)。Connection接口的setSavepoint和releaseSavepoint方法可以設(shè)置和釋放保存點(diǎn)。

TransactionStatus:事務(wù)狀態(tài)表現(xiàn)形式。

 3.3.3 spring事務(wù)實(shí)現(xiàn)機(jī)制

1 高層

比較好的方式有:1.基于持久層api的模板方法;2.使用具有事務(wù)工廠bean的本地ORM api;3使用代理管理本地資源工廠。

2 底層

      DataSourceUtils (用作JDBC事務(wù)), EntityManagerFactoryUtils (用作JPA事務(wù)), SessionFactoryUtils (用作Hibernate事務(wù)),PersistenceManagerFactoryUtils (用作JDO事務(wù))等等,

例如:在使用jdbc時(shí),你可以不通過DataSource的getConnection()方法獲取connection,而是使用以下方法獲取:

  Connection conn = DataSourceUtils.getConnection(dataSource);
3 最低層
TransactionAwareDataSourceProxy是事務(wù)的最底層,它代理了DataSource,并增加了spring管理事務(wù)功能。
參考資料:
1.http://www.educity.cn/rk/457230.html
2. http://uule.iteye.com/blog/1445678
3. http://zhxing.iteye.com/blog/368110

總結(jié)

以上是生活随笔為你收集整理的spring transaction源码分析--事务架构的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。