Spring事務(wù)管理

Spring框架為事務(wù)管理提供了一致的抽象,可以帶來以下好處:

  • Java Transaction API(JTA),JDBC,Hibernate,Java Persistence API(JPA)和Java數(shù)據(jù)對象(JDO)等不同的事務(wù)API之間的一致的編程模型
  • 支持聲明事務(wù)管理
  • 編程式事務(wù)管理的API使用簡單
  • 與Spring的數(shù)據(jù)訪問抽象集成

1、Spring一致的編程模型

傳統(tǒng)上,Java EE開發(fā)人員有兩種交易管理選擇:全局或本地交易,兩者都有明顯的局限性。

  • 全局事務(wù)
    JTA、EJB

優(yōu)點:可以多資源使用
缺點:JTA API笨重、通過JNDI獲取資源。

  • 本地事務(wù)
    本地事務(wù)是資源專用,比如:JDBC連接。

優(yōu)點:簡單易用。
缺點:不能多資源使用。

1.1、理解Spring事務(wù)抽象

Spring事務(wù)抽象最重要是事務(wù)策略概念,事務(wù)策略由org.springframework.transaction.PlatformTransactionManager定義:

public interface PlatformTransactionManager {

    TransactionStatus getTransaction(
            TransactionDefinition definition) throws TransactionException;

    void commit(TransactionStatus status) throws TransactionException;

    void rollback(TransactionStatus status) throws TransactionException;
}

TransactionStatus表示一個新的事務(wù)或者當(dāng)前調(diào)用堆棧中存在匹配事務(wù),和執(zhí)行線程相關(guān)聯(lián)。TransactionStatus實例需要依賴一個
TransactionDefinition實例參數(shù),TransactionDefinition接口定義如下:

public interface TransactionDefinition {

    // 事務(wù)傳播
    int getPropagationBehavior();

    // 事務(wù)隔離級別
    int getIsolationLevel();

    // 事務(wù)超時事務(wù)
    int getTimeout();

    boolean isReadOnly();

    String getName();

}

TransactionStatus接口定義:

public interface TransactionStatus extends SavepointManager, Flushable {

    boolean isNewTransaction();

    boolean hasSavepoint();

    void setRollbackOnly();

    boolean isRollbackOnly();

    void flush();

    boolean isCompleted();

}

1.2、理解聲明式事務(wù)

關(guān)于Spring Framework的聲明式事務(wù)支持的最重要的概念是通過AOP代理啟用此支持,并且事務(wù)性建議由元數(shù)據(jù)驅(qū)動(目前基于XML或基于注釋的),AOP與事務(wù)元數(shù)據(jù)的組合產(chǎn)生一個AOP代理,它使用TransactionInterceptor與適當(dāng)?shù)腜latformTransactionManager實現(xiàn)結(jié)合來驅(qū)動方法調(diào)用的事務(wù)。

事務(wù)調(diào)用過程如下:

事務(wù)調(diào)用過程

1.2.1、聲明式事務(wù)示例

  • 基于XML方式

    (1)創(chuàng)建對應(yīng)數(shù)據(jù)庫DO

        public class User {
    
        private Integer id;
    
        private String name;
        
        private Integer age;
    
        private Integer sex;
    
        public User(Integer id, String name, Integer age, Integer sex) {
            this.id = id;
            this.name = name;
            this.age = age;
            this.sex = sex;
        }
    
        public Integer getId() {
            return id;
        }
    
        public void setId(Integer id) {
            this.id = id;
        }
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    
        public Integer getAge() {
            return age;
        }
    
        public void setAge(Integer age) {
            this.age = age;
        }
    
        public Integer getSex() {
            return sex;
        }
    
        public void setSex(Integer sex) {
            this.sex = sex;
        }
    }
    

    (2)、創(chuàng)建表與實體間映射

    public class UserRowMapper implements RowMapper<User>{
    
            public User mapRow(ResultSet resultSet, int i) throws SQLException {
    
                User person = new User(
                            resultSet.getInt("id"),
                            resultSet.getString("name"),
                            resultSet.getInt("age"),
                            resultSet.getInt("sex"));
                return person;
            }
        } 
    
    

    (3)、創(chuàng)建UserService接口

    public interface UserService {
    
                void save(User user);
    }
    

    (4)、創(chuàng)建UserService接口實現(xiàn)類

    public class UserServiceImpl implements UserService {
    
        private final static Logger logger = LoggerFactory.getLogger(UserServiceImpl.class);
    
        @Resource
        private JdbcTemplate jdbcTemplate;
    
        @Override
        public void save(User user) {
    
            jdbcTemplate.update("INSERT INTO user(name,age,sex) VALUES (?,?,?)",
                    new Object[]{user.getName(), user.getAge(), user.getSex()},
                    new int[]{Types.VARCHAR, Types.INTEGER, Types.VARCHAR});
        }
    }
    

    (5)、創(chuàng)建Spring配置文件

        <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
            <property name="driverClass" value="com.mysql.jdbc.Driver"/>
            <property name="jdbcUrl" value="jdbc:mysql://localhost:3306/test"/>
            <property name="user" value="root"/>
            <property name="password" value="root"/>
        </bean>
    
        <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
            <property name="dataSource" ref="dataSource"/>
        </bean>
    
        <bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
            <property name="dataSource" ref="dataSource"/>
        </bean>
    
        <tx:advice id="txAdvice" transaction-manager="txManager">
            <!-- the transactional semantics... -->
            <tx:attributes>
                <!-- all methods starting with 'get' are read-only -->
                <tx:method name="get*" read-only="true"/>
                <!-- other methods use the default transaction settings (see below) -->
                <tx:method name="*"/>
            </tx:attributes>
        </tx:advice>
    
    
        <aop:config>
            <aop:pointcut id="serviceOperation"
                        expression="execution(* com.codersm.study.spring.tx.service.UserService.*(..))"/>
            <aop:advisor advice-ref="txAdvice" pointcut-ref="serviceOperation"/>
        </aop:config>
    
        <bean id="userService" class="com.codersm.study.spring.tx.service.impl.UserServiceImpl"/>
    
  • 基于注解方式

1.3、事務(wù)傳播

1.4、其他

1.4.1、Using @Transactional with AspectJ

It is also possible to use the Spring Framework’s @Transactional support outside of a Spring container by means of an AspectJ aspect.

1.4.2、事務(wù)綁定事件

1.5 源碼分析

<<tx:advice>>標(biāo)簽 = org.springframework.transaction.interceptor.TransactionInterceptor

image.png
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 對大多數(shù)Java開發(fā)者來說,Spring事務(wù)管理是Spring應(yīng)用中最常用的功能,使用也比較簡單。本文主要從三個方...
    sherlockyb閱讀 3,287評論 0 18
  • 事務(wù)是一組操作的原子執(zhí)行,其中任何一筆操作失敗將導(dǎo)致全部操作撤銷。 什么是事務(wù)? 如上所言,事務(wù)遵循ACID原則,...
    點融黑幫閱讀 7,923評論 3 36
  • 這部分的參考文檔涉及數(shù)據(jù)訪問和數(shù)據(jù)訪問層和業(yè)務(wù)或服務(wù)層之間的交互。 Spring的綜合事務(wù)管理支持覆蓋很多細(xì)節(jié),然...
    竹天亮閱讀 1,101評論 0 0
  • 一、spring事務(wù)介紹 spring事務(wù)優(yōu)點 對不同的api進(jìn)行統(tǒng)一編程模型,如JTA,JDBC,Hiberna...
    青芒v5閱讀 7,923評論 2 22
  • spring支持編程式事務(wù)管理和聲明式事務(wù)管理兩種方式。 編程式事務(wù)管理使用TransactionTemplate...
    熊熊要更努力閱讀 288評論 0 0

友情鏈接更多精彩內(nèi)容