Spring 事务管理

1. 事务的概念与特性

事务指的是逻辑上的一组操作,这组操作要么全部成功,要么全部失败;用统一的机制来处理不同数据访问技术的事务处理;

特性描述
原子性-atomicity事务中的各个操作不可单独执行,要么整体发生,要么整体不发生
一致性-consistency事务执行前后的数据完整性必需保持一致
隔离性-isolation事务执行过程中不应该被其他事务干扰,多个并发事务之间的数据要互相隔离
持久性-durability一个事务一旦提交,数据库中数据的改变就是永久性的

2. 事务管理 API

由 Spring 提供常用的 3 个 API 实现事务的管理

2.1 PlatformTransactionManager-事务管理器

常用事务描述
org.springframework.jdbc.datasource.DataSourceTransactionManagerSpring JDBC 或 Batis 进行持久化数据使用
org.springframework.orm.hibernate3.HibernateTransactionManagerHiberbate 3.0 版本进行持久化数据使用

2.2 TransactionDefinition-事务定义信息

隔离级别描述
READ_UNCOMMITED最低隔离级别,充许别外一个事务可以看到这个事务未提交的数据。这种隔离级别会产生脏读,不可重复读和幻像读
READ_COMMITTED保证一个事务修改的数据提交后才能被另外一个事务读取。另外一个事务不能读取该事务未提交的数据。这种事务隔离级别可以避免脏读出现,但是可能会出现不可重复读和幻像读
REPEAtABLE_READ防止脏读,不可重复读。但是可能出现幻像读。它除了保证一个事务不能读取另一个事务未提交的数据外,还保证了避免下面的情况产生(不可重复读)
SERIALIZABLE花费最高代价但是最可靠的事务隔离级别,事务被处理为顺序执行。除了防止脏读,不可重复读外,还避免了幻像读
传播行为描述
REQUIRED支持当前事务,如果不存在则创建
SUPPORTS支持当前事务,如果不存在就不使用
MANDATORY支持当前事务,如果不存在便抛出异常
REQUIRES_NEW如果有事务存在,挂起事务并创建新事物
NOT_SUPPORTED以非事务方式运行,如果事务存在则挂起当前事务
NEVER以非事务方式运行,如果事务存在则抛出异常
NESTED如果当前事务存在,则嵌套事务执行

2.3 TransactionStatus-事务状态表现形式


3. 事务管理方式

3.1 编程式事务管理

  • 业务类实现.class
public class ServiceImpl{

    // 注入事务管理的模板
    private TransactionTemplate transactionTemplate;

    public void setTransactionTemplate(TransactionTemplate t){
        this.transactionTemplate = t;
    }

    // 某个测试业务方法
    public void tansactionTest(){
        transactionTemplate.execute(new TransactionCallbackWithoutResult()){
            @Override
            protected void doInTransactionWithResult(TransactionStatus transactionStatus){
                // 此处可以开始执行事务中的相关操作
            }
        }
    }
}
  • 编辑配置文件.xml
<beans ...>

    <!-- 配置c3p0连接池 -->
    <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
        <property name="driverClass" value="${jdbc.driverClass}"/>
        <property name="jdbcUrl" value="${jdbc.url}"/>
        <property name="user" value="${jdbc.username}"/>
        <property name="password" value="${jdbc.password}"/>
    </bean>

    <!-- 配置事务管理器,关联连接池 -->
    <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="dataSource"/>
    </bean>

    <!-- 配置事务管模板,事务包装 -->
    <bean id="transactionTemplate" class="org.springframework.transaction.support.TransactionTemplate">
        <property name="transactionManager" ref="transactionManager"/>
    </bean>

    <!-- 业务类,模板应用 -->
    <bean id="service" class="com...ServiceImpl">
        <!-- 注入事务管理的模板 -->
        <property name="transactionTemplate" ref="transactionTemplate"/>
    </bean>

</beans>

3.2 声明式事务管理 - 推荐

3.2.1 基于 TransactionProxyFactoryBean 方式

需为每个事务管理的类都配置一个 TransactionProxyFactoryBean 。需要引入两包:

  • com.springsource.org.aopalliance.jar
  • spring-aop.jar
  • 业务类实现.class
public class ServiceImpl{

    // 某个测试业务方法
    public void tansactionTest(){
        // 此处可以开始执行事务中的相关操作
    }
}
  • 编辑配置文件.xml
<beans ...>

    <!-- 配置c3p0连接池 -->
    <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
        <property name="driverClass" value="${jdbc.driverClass}"/>
        <property name="jdbcUrl" value="${jdbc.url}"/>
        <property name="user" value="${jdbc.username}"/>
        <property name="password" value="${jdbc.password}"/>
    </bean>

    <!-- 业务类 -->
    <bean id="service" class="com...ServiceImpl"></bean>

    <!-- 配置事务管理器,关联连接池 -->
    <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="dataSource"/>
    </bean>

    <!-- 业务层代理-->
    <bean id="accountServiceProxy" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean"
        <!-- 关联目标对象 -->
        <property name="target" ref="service"/>
        <!-- 注入事务管理器 -->
        <property name="transactionManager" ref="transactionManager"/>
        <!-- 注入事务属性,代替目标对象完成注入工作 -->
        <property name="transactionAtteributes">
            <props>
                <!--
                    prop 格式:
                        PROPAGATION : 事务的传播行为;
                        ISOLATION   : 事务的隔离级别;
                        readOnly    : 只读;
                        -Exception  : 指定发生异常执行回滚;
                        +Exception  : 指定发生异常依然提交事务,不自信回滚;
                -->
                <prop key"transfer">PROPAGATION_REQUIRED</prop>
            </props>
        </property>
    </bean>
</beans>
3.2.2 基于 AspectJ 方式

只需在 xml 配置中实现事务的增强式管理,而对应的类无需任何操作。需要引入两包:

  • com.springsource.org.aspectj.weaver.jar
  • spring-aspects.jar
  • 业务类实现.class
public class ServiceImpl{

    // 某个测试业务方法
    public void tansactionTest(){
        // 此处可以开始执行事务中的相关操作
    }
}
  • 编辑配置文件.xml
<beans ...>

    <!-- 配置c3p0连接池 -->
    <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
        <property name="driverClass" value="${jdbc.driverClass}"/>
        <property name="jdbcUrl" value="${jdbc.url}"/>
        <property name="user" value="${jdbc.username}"/>
        <property name="password" value="${jdbc.password}"/>
    </bean>

    <!-- 业务类 -->
    <bean id="service" class="com...ServiceImpl"></bean>

    <!-- 配置事务管理器,关联连接池 -->
    <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="dataSource"/>
    </bean>

    <!-- 配置事务的通知:(事务增强) -->
    <tx:advice id="txAdvice" transaction-manager"="transactionManager">
        <tx:attributes>
            <!--
                propagation    : 事务的传播行为;
                isolation      : 事务的隔离级别;
                read-only      : 只读;
                rollback-for   : 指定发生异常执行回滚;
                no-rollback-for: 指定发生异常依然提交事务,不自信回滚;
                timeout        : 过期信息;
            -->
            <tx:method name="transfer" propagation="REQUIRED"/>
        </tx:attributes>
    </tx:advice>

    <!-- 配置切面 -->
    <aop:config>
        <!-- 设定切入点 -->
        <aop:pointcut expression="execution(* com...ServiceImpl+.*(..))" id="pointcut"/>
        <!-- 设定切面 -->
        <aop:advisor advice-ref="txAdvice" pointcut-ref="pointcut"/>
    </aop:config>
</beans>
3.2.2 基于注解方式

除 xml 配置并开启事务以外,还需要为每个事务管理类添加相应的注解信息。

  • 业务类实现.class
/*
propagation    : 事务的传播行为;
isolation      : 事务的隔离级别;
readOnly       : 只读;
rollbackFor    : 指定发生异常执行回滚;
noRollbackFor  : 指定发生异常依然提交事务,不自信回滚;

注意:方法亦可以加该注解,标识覆盖类声明的注解信息。
*/
@Transactional(propagation=Propagation.REQUIRED)
public class ServiceImpl{

    // 某个测试业务方法
    public void tansactionTest(){
        // 此处可以开始执行事务中的相关操作
    }
}
  • 编辑配置文件.xml
<beans ...>

    <!-- 配置c3p0连接池 -->
    <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
        <property name="driverClass" value="${jdbc.driverClass}"/>
        <property name="jdbcUrl" value="${jdbc.url}"/>
        <property name="user" value="${jdbc.username}"/>
        <property name="password" value="${jdbc.password}"/>
    </bean>

    <!-- 业务类 -->
    <bean id="service" class="com...ServiceImpl"></bean>

    <!-- 配置事务管理器,关联连接池 -->
    <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="dataSource"/>
    </bean>

    <!-- 开启注解事务,配置文件.class 可用 @EnableTransactionManagement 启用事务 -->
    <tx:annotation-driven transaction-manager="transactionManager"/>
</beans>
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值