1. 程式人生 > >Spring 事務學習筆記(1):事務的基本知識

Spring 事務學習筆記(1):事務的基本知識

一、事務&&JDBC事務支援

在我的之前的spring操作資料庫中的文章很少提及事務,不是說它不重要,而是太重要,以至於spring專門有一部分來說明這一內容。之前可以說對事務幾乎沒有考慮過,只是知道把要進行的操作被事務包裹起來,就像在hibernate中進行的操作一樣,如下:

Session session = factory.openSession();  
Transaction transaction = session.beginTransaction();  
session.save(...);
transaction.commit();  
session.close(); 
另外知道事務是保證操作的原子性,即ACID中的那個A。所以關於事務的內容提前看了好多,看如下的第一個連結。

另外JDBC也提供了對資料庫事務的操作,典型的JDBC事務資料操作如下:

try {
	Class.forName("");
} catch (ClassNotFoundException e) {
	e.printStackTrace();
}
Connection conn = null;
Savepoint savepoint = null;
try {
	conn = DriverManager.getConnection("");
	conn.setAutoCommit(false);
	conn.setTransactionIsolation(Connection.TRANSACTION_SERIALIZABLE);
	Statement statement = conn.createStatement();
	statement.executeQuery("sql1");
	savepoint = conn.setSavepoint("sql1");
	statement.executeQuery("sql2");
			
	conn.commit();
} catch (SQLException e) {
	try {
		if(savepoint == null){
			conn.rollback();
		}
		else{
			conn.rollback(savepoint);
		}
	} catch (SQLException e1) {
		e1.printStackTrace();
	}
	e.printStackTrace();
}

JDBC中的Connection是預設自動提交的,也就是每執行一條SQL語句就對應一個事務,所以我們首先要禁止掉讓它預設提交,所以設定為setAutoCommit(false),如果發生執行時異常則會發生回滾rollback(),另外還可以通過setTransactionIsolation()設定隔離級別(至於什麼是隔離級別,看如下的相關文章)。另外還有一點在我寫這篇之前我是不知道還有儲存點這回事的,什麼是儲存點呢?也就是一個事務中可能要執行多個SQL語句,之前回滾的時候只能回滾到執行所有SQL之前,但是現在我們可以只回滾到執行某個SQL語句之前,而不必要撤銷所有的SQL語句,如上面SavePoint 的使用。

二、Spring對事務的支援初步

Spring對事務的支援可以分成兩種,一是程式設計式事務管理,什麼意思,說白了就是寫程式碼實現事務管理,就是向我們上邊的JDBC對事務的管理的方式,每執行一次對資料庫的操作都要加上事務的模板程式碼;一種是宣告式事務管理,就是通過註解和XML配置檔案的方式來完成對事務的管理,就像我們前面中說到的對Bean管理,可以想象一下通過什麼樣的手段來完成這種型別的事務管理?前面我們說到AOP這種思想,可以想象我們可以通過這種手段來實現把對資料庫的操作放到一個類似於容器(自造)中來管理。Spring實際上就是通過AOP來完成對事務的管理的。 Spring提供了一種事務機制,這種機制不管底層的實現具體是JDBC,還是Hibernate、myBatis等,它的處理方式都是類似的,也就是Spring構建了一個抽象層,能夠和底層具體的事務技術相獨立,這就為我們提供了方便。 Spring的核心事務管理物件是PlatformTransactionManager,它只提供了三個方法,其中我們熟悉的有commit()和rollback()。它有一個實現類AbstractPlatformTransactionManager,這個實現類也有兩個實現類:
  • DataSourceTransactionManager:管理一個數據源,並且通過JDBC來完成對資料庫的操作;
  • JtaTransactionManager:使用JTA進行事務管理;
以上的事務管理器的使用方式:
<!-- config transaction manager -->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
	<property name="dataSource" ref="dataSource"></property>
</bean>
	
<!-- enable transaction annotation -->
<tx:annotation-driven transaction-manager="transactionManager"/>
首先配置事務管理器,它需要一個數據源屬性,然後開啟事務註解,屬性transaction-manager的值也是transactionManager,如果預設是這個值則不需要配置這個屬性
public class PersonDao {
	@Autowired
	private JdbcTemplate jdbcTemplate;

	public JdbcTemplate getJdbcTemplate() {
		return jdbcTemplate;
	}

	public void setJdbcTemplate(JdbcTemplate jdbcTemplate) {
		this.jdbcTemplate = jdbcTemplate;
	}
	
	@Transactional
	public void update(int age){
		jdbcTemplate.update("insert into user(username, address, age) values(?,?,?)", "abc", "hz", age);
		if(age < 20){
			throw new OperationException("");
		} 
	}
}
使用@Transactional來標識到一個方法,我們的自定義一個執行時異常(注意只有RuntimeException才會rollback),可以看到方法發生異常的時候資料不會插入,但是沒有該註解,則會插入資料並會報出異常。

相關文章: