编程式事务处理

這邊以一個簡單的例子來示範Spring的事務管理,對於事務管理定義,我們使用Spring提供的DefaultTransactionDefinition。

  以JDBC DataSource為例,我們可以使用org.springframework.jdbc.datasource.DataSourceTransactionManager(PlatformTransactionManager的一個實現)作為我們的事務管理員,我們在Bean定義檔中配置,並將DataSource注入給它,例如:

 代碼:

<?xml version="1.0" encoding="UTF-8"?> 
<!DOCTYPE beans PUBLIC "-//SPRING/DTD BEAN/EN" "http://www.springframework.org/dtd/spring-beans.dtd"> 
<beans> 
    <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource"> 
        <property name="driverClassName"> 
            <value>com.mysql.jdbc.Driver</value> 
        </property> 
        <property name="url"> 
            <value>jdbc:mysql://localhost:3306/TestDB</value> 
        </property> 
        <property name="username"> 
            <value>root</value> 
        </property> 
        <property name="password"> 
            <value></value> 
        </property> 
    </bean> 

    <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> 
        <property name="dataSource"> 
            <ref bean="dataSource"/> 
        </property>    
    </bean> 
                                                                                
    <bean id="userDAO" class="onlyfun.caterpillar.UserDAO"> 
        <property name="dataSource"> 
            <ref bean="dataSource"/> 
        </property> 
        <property name="transactionManager"> 
            <ref bean="transactionManager"/> 
        </property> 
    </bean> 
</beans>

  我們定義了一個簡單的DAO物件,將transactionManager與dataSource注入至其中,UserDAO如下:

 代碼:

UserDAO.java
package onlyfun.caterpillar; 

import javax.sql.DataSource; 
import org.springframework.jdbc.core.*; 
import org.springframework.transaction.*; 
import org.springframework.transaction.support.*; 
import org.springframework.dao.*; 

public class UserDAO { 
    private DataSource dataSource; 
    private PlatformTransactionManager transactionManager; 

    public void setDataSource(DataSource dataSource) { 
        this.dataSource = dataSource; 
    } 
    
    public void setTransactionManager(PlatformTransactionManager transactionManager) { 
        this.transactionManager = transactionManager; 
    } 

    public void insertUser(User user) { 
        .... 
    } 
}

  insertUser()方法中,我們將實現User的存儲,並使用事務管理,首先看看直接使用trransactionManager如何實現事務,我們需要事務定義,作為示範,這邊先使用Spring預設的即可:DefaultTransactionDefinition,我們的程式示範如下:

 代碼:

DefaultTransactionDefinition def = new DefaultTransactionDefinition(); 
TransactionStatus status = transactionManager.getTransaction(def); 
    try { 
        JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource); 
        jdbcTemplate.update("INSERT INTO USER VALUES('Spring008', 'caterpillar', 'M', 29)"); 
        jdbcTemplate.update("INSERT INTO USER VALUES('Spring009', 'momor', 'F', 26)"); 
        jdbcTemplate.update("INSERT INTO USER VALUES('Spring010, 'beckyday', 'F', 35)"); 
        
    } catch (DataAccessException ex) { 
        transactionManager.rollback(status); // 也可以執行status.setRollbackOnly(); 
        throw ex; 
    } 
    transactionManager.commit(status);

  在上面的程式中,我們照常執行我們的SQL(為了簡化,我們直接將資料寫在SQL中了,而不是從User物件中取得),注意到我們故意在最後一行SQL中Spring010少寫了一個 ' ,這使得SQL句子不合語法,因而造成DataAccessException(封裝了SQLException),這個例外被catch區塊捕捉,因而執行rollback()取消之後的SQL,如果沒有發生錯誤,則最後我們使用commit()來提交操作。

  另一個簡便的方法是使用TransactionTemplate,它封裝了上面的事務流程,透過callback來完成事務,例如:

 代碼:

TransactionTemplate transactionTemplate = new TransactionTemplate(transactionManager); 
transactionTemplate.execute(new TransactionCallbackWithoutResult() { 
        public void doInTransactionWithoutResult(TransactionStatus status) { 
            JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource); 
            jdbcTemplate.update("INSERT INTO USER VALUES('Spring008', 'caterpillar', 'M', 29)"); 
            jdbcTemplate.update("INSERT INTO USER VALUES('Spring009', 'momor', 'F', 26)"); 
            jdbcTemplate.update("INSERT INTO USER VALUES('Spring010, 'beckyday', 'F', 35)"); 
        } 
    });

  這邊使用TransactionCallbackWithoutResult,並在它的doInTransactionWithoutResult()中進行SQL操作,如果執行中發生例外,則之前所有的操作取消,否則最後自動提交操作。如果操作完成您想要返回結果物件,則可以使用TransactionCallback,並實現其doInTransaction(),例如:

 代碼:

TransactionTemplate transactionTemplate = new TransactionTemplate(transactionManager); 
Object result = transactionTemplate.execute( 
    new TransactionCallback() { 
        public Object doInTransaction(TransactionStatus status) { 
            // 作一些操作 
            // 收集為結果物件 resultObject 

            return resultObject; 
        });
 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值