Spring事务

2018-07-07  本文已影响0人  萧衍_

一. 事务特性ACID

二. 事务管理器

Spring并不直接管理事务,而是提供事务管理器接口,让框架自己(包括JDBC、hibernate、JPA、JTA等)实现具体的事务管理。

2.1 spring提供的事务管理器接口

包括3个接口:获取事务状态、提交、回滚

package org.springframework.transaction;

public interface PlatformTransactionManager {
    TransactionStatus getTransaction(TransactionDefinition var1) throws TransactionException;

    void commit(TransactionStatus var1) throws TransactionException;

    void rollback(TransactionStatus var1) throws TransactionException;
}

2.2 具体实现(以JDBC为例)

DataSourceTransactionManager通过DataSource获取到java.sql.Connection,再调用java.sql.Connection来管理事务

<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="具体数据源"></property>
</bean>

<tx:annotation-driven transaction-manager="transactionManager"/>

三. 事务基本属性

上文提到的spring事务管理器接口中,用于获取事务状态的getTransaction方法参数定义了一个事务的基本属性

TransactionStatus getTransaction(TransactionDefinition var1)

事务基本属性包括5类:

public interface TransactionDefinition {

    int getPropagationBehavior();

    int getIsolationLevel();

    int getTimeout();

    boolean isReadOnly();

    String getName();
}

3.1 传播行为 PROPAGATION

定义一个事务被另一个事务调用时,两个事务之间的关系,如:被调用事务合并到调用事务中运行,或者独立开启一个新事务运行等。

Spring定义了七种传播行为:

3.2 隔离级别

定义了一个事务可能受其他并发事务影响的程度

1.并发事务问题:

不可重复读的重点是同一个数据被修改了,幻读的重点在于有数据新增或者删除。

从结果看, 似乎不可重复读和幻读都表现为两次读取的结果不一致。但如果从控制的角度来看, 两者的区别就比较大:

2.隔离级别

3.3 是否只读

如果事务只对数据库进行读操作,则数据库可以进行一些特定的优化。通过将事务设置为只读,你就可以给数据库一个机会,让它应用它认为合适的优化措施。

3.4 超时时间

事务超时就是事务的一个定时器,在特定时间内事务如果没有执行完毕,那么就会自动回滚,而不是一直等待其结束。

3.5 回滚规则

默认情况下,事务只有遇到运行期异常时才会回滚,而在遇到检查型异常时不会回滚(这一行为与EJB的回滚行为是一致的)

但是你可以声明事务在遇到特定的检查型异常时像遇到运行期异常那样回滚。同样,你还可以声明事务遇到特定的异常不回滚,即使这些异常是运行期异常。

四. spring事务实现方式

4.1 编程式事务

4.2 声明式事务

4.3 demo(声明式事务,全注解方式)

使用@Transactional注解

/**
     * 1.propagation 指定事务的传播行为
     * 默认取值为REQUIRED,即使用调用方法的事务
     * 设置为REQUIRES_NEW,即使用自己的事务,调用方法的事务被挂起
     * 2.isolation 指定事务的隔离级别,最常用的取值为READ_COMMITTED
     * 3.Spring 的声明式事务默认对所有运行时异常进行回滚,也可以通过对应的属性进行自行设置
     * 4.readOnly 指定事务是否为只读,若这个事务只读取数据则设置为true,可帮助数据库引擎优化事务
     * 5.timeOut 指定强制回滚之前事务可以占用的时间
     */
    @Transactional(propagation=Propagation.REQUIRES_NEW,
            isolation=Isolation.READ_COMMITTED,
            noRollbackFor={UserAccountException.class},
            readOnly=true, timeout=3)
    @Override
    public void purchase(String username, String isbn) {
        //1.获取书的单价
        int price = bookShopDao.findBookPriceByIsbn(isbn);
        //2.更新书的库存
        bookShopDao.updateBookStock(isbn);
        //3.更新用户余额
        bookShopDao.updateUserAccount(username, price);
    }

测试事务的传播行为

@Transactional
    @Override
    public void checkout(String username, List<String> isbns) {
        for(String isbn : isbns) {
            bookShopService.purchase(username, isbn);
        }
    }
上一篇下一篇

猜你喜欢

热点阅读