Spring事务管理

目录

事务的基本原理

事务的理论

Spring的事务管理

Spring事务管理核心

Spring事务的传播属性

Spring事务的隔离级别

编程式事务管理

声明式事务管理(通过aop实现)

1.基于tx和aop命名空间的xml配置文件

2.基于@Transactional注解


事务的基本原理

Spring事务的本质其实就是数据库对事务的支持,使用JDBC的事务管理机制,就是利用java.sql.Connection对象完成对事务的提交.

事务是一系列的动作,一旦其中有一个动作出现错误,必须全部回滚,系统将事务中对数据库的所有已完成的操作全部撤消,滚回到事务开始的状态,避免出现由于数据不一致而导致的接下来一系列的错误。事务的出现是为了确保数据的完整性和一致性,在目前企业级应用开发中,事务管理是必不可少的。

事务的理论

众所周知,事务有四大特性(ACID)

1.原子性(Atomicity)事务是一个原子操作,由一系列动作组成。事务的原子性确保动作要么全部完成,要么完全不起作用。

2.一致性(Consistency)事务在完成时,必须是所有的数据都保持一致状态。

3.隔离性(Isolation)并发事务执行之间无影响,在一个事务内部的操作对其他事务是不产生影响,这需要事务隔离级别来指定隔离性。

4.持久性(Durability)一旦事务完成,数据库的改变必须是持久化的。

在企业级应用中,多用户访问数据库是常见的场景,这就是所谓的事务的并发。事务并发所可能存在的问题:
1.脏读:一个事务读到另一个事务未提交的更新数据。
2.不可重复读:一个事务两次读同一行数据,可是这两次读到的数据不一样。
3.幻读:一个事务执行两次查询,但第二次查询比第一次查询多出了一些数据行。
4.丢失更新:撤消一个事务时,把其它事务已提交的更新的数据覆盖了。

在java.sql.Connection中看到JDBC定义了五种事务隔离级别来解决这些并发导致的问题

TRANSACTION_NONE JDBC 驱动不支持事务
TRANSACTION_READ_UNCOMMITTED 允许脏读、不可重复读和幻读。
TRANSACTION_READ_COMMITTED 禁止脏读,但允许不可重复读和幻读。
TRANSACTION_REPEATABLE_READ 禁止脏读和不可重复读,单运行幻读。
TRANSACTION_SERIALIZABLE 禁止脏读、不可重复读和幻读。

出于性能的考虑我们一般设置TRANSACTION_READ_COMMITTED就差不多了,剩下的通过使用数据库的锁来帮我们处理。

Spring的事务管理

有了Spring,我们再也无需要去处理获得连接、关闭连接、事务提交和回滚等这些操作,使得我们把更多的精力放在处理业务上。

Spring事务管理核心

Spring事务管理的核心接口是PlatformTransactionManager
这里写图片描述

主要的方法有:

int getIsolationLevel();// 返回事务的隔离级别
String getName();// 返回事务的名称
int getPropagationBehavior();// 返回事务的传播行为
int getTimeout();  // 返回事务必须在多少秒内完成
boolean isReadOnly(); // 事务是否只读,事务管理器能够根据这个返回值进行优化,确保事务是只读的

Spring事务的传播属性

Spring定义了7个以PROPAGATION_开头的常量表示它的传播属性。

Spring事务的隔离级别

Spring提供了两种事务管理的方式:编程式事务管理和声明式事务管理,让我们分别看看它们是怎么做的吧。

编程式事务管理

1. 首先配置事务管理器

spring-mybatis.xml

    <bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="dataSource"/>
    </bean>

2.在业务中注入事务管理器

    private PlatformTransactionManager platformTransactionManager;

    public void setPlatformTransactionManager(PlatformTransactionManager platformTransactionManager) {
        this.platformTransactionManager = platformTransactionManager;
    }

	@Override
    public void save(Student student) {
        // 创建事务配置对象
        DefaultTransactionDefinition transactionDefinition = new DefaultTransactionDefinition();
        // 获取事务状态
        TransactionStatus status = platformTransactionManager.getTransaction(transactionDefinition);
        try {
            studentMapper.save(student);
            // 提交事务
            platformTransactionManager.commit(status);
        } catch (TransactionException e) {
            e.printStackTrace();
            // 回滚事务操作
            platformTransactionManager.rollback(status);
        } finally {
            System.out.println("执行完毕!");
        }
    }

声明式事务管理(通过aop实现)

声明式事务管理有两种常用的方式,一种是基于tx和aop命名空间的xml配置文件,一种是基于@Transactional注解,随着Spring和Java的版本越来越高,大家越趋向于使用注解的方式。

1.基于tx和aop命名空间的xml配置文件
    <tx:advice id="advice" transaction-manager="transactionManager">
        <tx:attributes>
            <tx:method name="insert" propagation="REQUIRED" read-only="false"  rollback-for="Exception"/>
        </tx:attributes>
    </tx:advice>

    <aop:config>
        <aop:pointcut id="pointCut" expression="execution (* com.gray.service.*.*(..))"/>
        <aop:advisor advice-ref="advice" pointcut-ref="pointCut"/>
    </aop:config>

通过xml实现事务管理太复杂

2.基于@Transactional注解


这种方式最简单,也是最为常用的,只需要在配置文件中开启对注解事务管理的支持。

    <!-- 声明式事务管理 配置事物的注解方式注入-->
    <tx:annotation-driven transaction-manager="txManager"/>

然后在需要事务管理的地方加上@Transactional注解,如:   

@Transactional(rollbackFor=Exception.class)
    public void insert(String sql, boolean flag) throws Exception {
        dao.insertSql(sql);
    }

rollbackFor属性指定出现Exception异常的时候回滚,遇到检查性的异常需要回滚,默认情况下非检查性异常,包括error也会自动回滚,可以通过@Transactional配置事务的各种属性

总结

spring事务管理方便了我们进行数据库事务的处理,一般通过声明式事务管理注解的方式来实现事务的处理,事务是面试的重点内容,需要牢牢掌握。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值