手動事務回滾和註解式事務配置及一些注意點

由於我們操作數據庫的時候可能會遇到相對應的異常,導致我們數據庫操作進行到一半,便停止,出現髒數據。所以這裏需要用到事務防止出現這種情況。關於註解的配置主要分爲兩類。一類是註解式事務,一類是xml聲明式事務。相對來說,註解式事務配置較爲簡單,代碼量較少,應用也較爲廣泛,所以這裏主要介紹註解式事務的配置。不過首先先介紹下手動回滾事務。
一、 手動回滾事務

		DefaultTransactionDefinition def = new DefaultTransactionDefinition();
		def.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED);
		PlatformTransactionManager txManager = ContextLoader.getCurrentWebApplicationContext().getBean(PlatformTransactionManager.class);
		TransactionStatus status = txManager.getTransaction(def);
		try {
			cardService.add();
			int x=1/0;
			txManager.commit(status);// 事務提交
		} catch (Exception e) {
			e.printStackTrace();
			txManager.rollback(status);// 事務回滾

		}

二、 註解式相關配置使用

  1. xml配置
<!-- ***********************事務配置************************** -->
	<bean id="dataSourceForFact" class="com.mchange.v2.c3p0.ComboPooledDataSource"
		destroy-method="close">
		<property name="driverClass" value="oracle.jdbc.driver.OracleDriver" />
		<property name="jdbcUrl" value="jdbc:oracle:thin:@localhost:1521:orcl" />
		<property name="user" value="scott" />
		<property name="password" value="oracle" />
		<property name="acquireIncrement" value="3" />
		<property name="initialPoolSize" value="3" />
		<property name="minPoolSize" value="2" />
		<property name="maxPoolSize" value="75" />
		<property name="maxIdleTime" value="600" />
		<property name="idleConnectionTestPeriod" value="900" />
		<property name="maxStatements" value="100" />
		<property name="numHelperThreads" value="10" />
	</bean>

	<bean id="sessionFactory"
		class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
		<!-- 集成hibernate.cfg.xml -->
		<property name="dataSource" ref="dataSourceForFact" />
		<property name="hibernateProperties">
			<props>
				<prop key="hibernate.dialect">org.hibernate.dialect.OracleDialect</prop>
				<prop key="hibernate.show_sql">true</prop>
			</props>
		</property>
		<!-- 集成hbm.xml -->
		<property name="packagesToScan" value="ffcs.cn" />
	</bean>

	<bean id="transactionManager"
		class="org.springframework.orm.hibernate3.HibernateTransactionManager">
		<property name="dataSource" ref="dataSource" />
		<property name="sessionFactory" ref="sessionFactory" />
	</bean>
	<tx:annotation-driven transaction-manager="transactionManager" />
  1. 方法調用
    爲了方便,我直接將註解放在類名上面,這樣子這個類的所有方法都默認調用這個註解
@Transactional(rollbackFor = Exception.class)
public class CardController {}

三、 注意點

  1. 一般事務的使用是在業務邏輯層。這樣子調用一個dao發生錯誤,即可回滾之前所調用的dao方法。 如何辨別哪一塊代碼層是業務邏輯層,只需要觀察哪一塊代碼層能夠實行多個數據庫操作。比如service層一個方法調用了多個dao即可認爲是業務邏輯層。亦或是一個service調用一個dao方法,而一個controller調用了多個sevice,則controller層即爲業務邏輯層。

  2. 一開始只使用@Transactional註解時候,設置1/0這種運行時異常,事務能夠正常回滾。但是遇到非運行時異常,卻發現sql操作不能回滾,這又是咋回事。俺不懂,查閱資料後,發現對於非運行時異常,我們需要添加配置(rollbackFor = Exception.class)才能夠回滾,當然你也可以使用TransactionAspectSupport.currentTransactionStatus()
    .setRollbackOnly();來手動回滾,如下

	try {
			cardService.add();
			throw new RuntimeException("Rollback");
		} catch (Exception e) {
			// 回滾操作
			TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
			System.out.println("出錯了");
		}
	
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章