Spring 允許我們將事務新增至程式碼中,而無需直接處理 JDBC 類別。為此,Spring 提供了一個事務管理套件,不僅取代了 JDBC 事務管理,還啟用了宣告式事務管理(組態而非程式碼)。
若要使用事務性資料庫存取,我們需要變更 world 資料庫中表格的儲存引擎。下載的指令碼明確建立 MyISAM 表格,這些表格不支援事務語意。InnoDB 儲存引擎支援事務,這也是我們將要使用的引擎。我們可以使用下列陳述式變更儲存引擎。
ALTER TABLE City ENGINE=InnoDB;
ALTER TABLE Country ENGINE=InnoDB;
ALTER TABLE CountryLanguage ENGINE=InnoDB;
Spring 強調的一個良好程式設計實務是分離介面和實作。這表示我們可以建立一個 Java 介面,並且只使用這個介面上的操作,而無需任何關於實際實作的內部知識。我們將讓 Spring 管理實作,並透過它來管理我們實作的事務。
首先,您建立一個簡單的介面
public interface Ex3Dao {
Integer createCity(String name, String countryCode,
String district, Integer population);
}
這個介面包含一個方法,該方法將在資料庫中建立新的城市記錄,並傳回新記錄的 ID。接下來,您需要建立此介面的實作。
public class Ex3DaoImpl implements Ex3Dao {
protected DataSource dataSource;
protected SqlUpdate updateQuery;
protected SqlFunction idQuery;
public Integer createCity(String name, String countryCode,
String district, Integer population) {
updateQuery.update(new Object[] { name, countryCode,
district, population });
return getLastId();
}
protected Integer getLastId() {
return idQuery.run();
}
}
您可以看到我們在這裡只操作抽象查詢物件,而沒有直接處理 JDBC API。此外,這是完整的實作。我們所有的事務管理都將在組態中處理。若要開始進行組態,我們需要建立 DAO。
<bean id="dao" class="code.Ex3DaoImpl">
<property name="dataSource" ref="dataSource"/>
<property name="updateQuery">...</property>
<property name="idQuery">...</property>
</bean>
現在我們需要設定事務組態。我們必須做的第一件事是建立一個事務管理器來管理資料來源,以及 dao
方法所需的事務屬性規格。
<bean id="transactionManager"
class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"/>
</bean>
<tx:advice id="txAdvice" transaction-manager="transactionManager">
<tx:attributes>
<tx:method name="*"/>
</tx:attributes>
</tx:advice>
前面的程式碼會建立一個事務管理器,用於處理為其提供的資料來源的事務。txAdvice
使用此事務管理器,而屬性指定為所有方法建立事務。最後,我們需要使用 AOP 切入點套用此建議。
<aop:config>
<aop:pointcut id="daoMethods"
expression="execution(* code.Ex3Dao.*(..))"/>
<aop:advisor advice-ref="txAdvice" pointcut-ref="daoMethods"/>
</aop:config>
這基本上表示在 Ex3Dao
介面上呼叫的所有方法都會包裝在事務中。若要使用它,我們只需從應用程式內容擷取 dao
,並在 dao
執行個體上呼叫方法。
Ex3Dao dao = (Ex3Dao) ctx.getBean("dao");
Integer id = dao.createCity(name, countryCode, district, pop);
我們可以從中驗證,我們的 Java 程式碼中沒有發生事務管理,並且所有事務管理都是透過 Spring 組態的。這是一個非常強大的概念,被視為 Spring 最有益的功能之一。