Spring 框架基础(05):事务管理机制,和实现方式

本文源码:GitHub·点这里 || GitEE·点这里

一、Spring事务管理

1、基础描述

Spring事务管理的本质就是封装了数据库对事务支持的操作,使用JDBC的事务管理机制,就是利用java.sql.Connection对象完成对事务的提交和回滚。

Connection conn = DriverManager.getConnection();
try {
    // 自动提交设置为false
    conn.setAutoCommit(false);
    // 执行增删改查操作
    // 当操作成功后手动提交
    conn.commit();
} catch (Exception e) {
    // 出现异常,回滚所有操作
    conn.rollback();
    e.printStackTrace();
} finally {
    conn.colse();
}

2、事务常见概念

  • 事务

事务是指作为单个逻辑工作单元执行的一系列操作(SQL语句)。这些操作要么全部成功,要么全部不成功。

  • 特性:ACID
原子性(Atomicity):事务中的多个操作要么都成功要么都失败
一致性(consistency):事务的执行的前后数据的完整性保持一致
隔离性(isolation):事务执行的过程中,不应该受到其他事务的干扰
持久性(durability):事务一旦结束,数据就持久到数据库
  • 隔离问题

脏读:一个事务读到另一个事务没有提交的数据

不可重复读:一个事务前后多次读取相同数据,数据内容不一致,update场景问题

虚读(幻读):一个事务前后多次读取,数据总量不一致,insert场景问题

  • 隔离级别

read uncommitted:

事务可以读取另一个未提交事务的数据。

read committed

事务要等另一个事务提交后才能读取数据,解决脏读。

repeatable read

在开始读取数据时,事务开启,不再允许修改操作,解决:脏读、不可重复读。

serializable

最高事务隔离级别,事务串行化顺序执行,解决脏读、不可重复读、幻读。但是效率低下,耗数据库性能。

3、事务管理API描述

  • PlatformTransactionManager

平台事务管理器,Spring管理事务,必须使用事务管理器进行事务配置时,核心方法:获取事务,提交事务,回滚事务。

  • TransactionDefinition

该对象封装事务详情(事务定义、事务属性),例如:隔离级别、是否只读、超时时间 等。

  • TransactionStatus

用于记录当前事务运行状态。例如:是否有保存点,事务是否完成。Spring底层根据状态进行相应操作。

4、事务案例SQL语句

CREATE TABLE user_account(
  id INT PRIMARY KEY AUTO_INCREMENT,
  username VARCHAR(50),
  money INT
) ENGINE=InnoDB DEFAULT CHARSET=utf8;;
INSERT INTO user_account(username,money) VALUES('jack','5000');
INSERT INTO user_account(username,money) VALUES('tom','5000');
SELECT * FROM user_account ;

二、编程式事务管理

1、核心配置文件

<!-- 配置事物管理器 -->
<bean id="txManager"
      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="txManager" />
</bean>
<!-- 配置转账接口 -->
<bean id="userAccountService"
      class="com.spring.mvc.service.impl.UserAccountServiceImpl">
    <property name="jdbcTemplate" ref="jdbcTemplate" />
    <property name="transactionTemplate" ref="transactionTemplate" />
</bean>

2、演示案例

@Service
public class UserAccountServiceImpl extends JdbcDaoSupport implements UserAccountService {
    // 注入事物模板
    private TransactionTemplate transactionTemplate ;
    public void setTransactionTemplate(TransactionTemplate transactionTemplate) {
        this.transactionTemplate = transactionTemplate;
    }
    @Override
    public void remittance(String remitTer, String receiver, int money) {
        transactionTemplate.execute(new TransactionCallbackWithoutResult() {
            public void doInTransactionWithoutResult(TransactionStatus arg0) {
                outMoney(remitTer,money);
                // System.out.println(1/0);
                innerMoney(receiver,money);
            }
        });
    }
    private void outMoney (String remitTer, int money){
        String outSql = "update user_account set money = money - ? where username = ?";
        this.getJdbcTemplate().update(outSql, money ,remitTer);
    }
    private void innerMoney (String receiver, int money){
        String inSql = "update user_account set money = money + ? where username = ?";
        this.getJdbcTemplate().update(inSql, money,receiver);
    }
}

三、事务代理工厂

1、核心配置

<!-- 配置转账接口 -->
<bean id="userAccountService01"
      class="com.spring.mvc.service.impl.UserAccountServiceImpl01">
    <property name="jdbcTemplate" ref="jdbcTemplate" />
</bean>
<!-- 配置事务代理工厂 -->
<bean id="proxyAccountService"
      class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
    <property name="proxyInterfaces" value="com.spring.mvc.service.UserAccountService01" />
    <property name="target" ref="userAccountService01" />
    <property name="transactionManager" ref="txManager" />
    <property name="transactionAttributes">
        <props>
            <!-- 默认传播行为、隔离级别 -->
            <prop key="remittance">PROPAGATION_REQUIRED,ISOLATION_DEFAULT</prop>
            <!-- 异常仍然提交事务
            <prop key="remittance">PROPAGATION_REQUIRED,ISOLATION_DEFAULT,+java.lang.Exception</prop>
            -->
        </props>
    </property>
</bean>

配置说明:

  • proxyInterfaces 代理接口
  • target 代理目标类
  • transactionManager 事务管理器
  • transactionAttributes 事务属性(事务详情)
  • prop.key 指定方法使用当前事务配置

事务行为:

  • PROPAGATION 传播行为
  • ISOLATION 隔离级别
  • readOnly 是否只读
  • -Exception 异常回滚
  • +Exception 异常提交

2、演示案例

@Service
public class UserAccountServiceImpl01 extends JdbcDaoSupport implements UserAccountService01 {
    @Override
    public void remittance(String remitTer, String receiver, int money) {
        outMoney(remitTer,money);
        System.out.println(1/0);
        innerMoney(receiver,money);
    }
    private void outMoney (String remitTer, int money){
        String outSql = "update user_account set money = money - ? where username = ?";
        this.getJdbcTemplate().update(outSql, money ,remitTer);
    }
    private void innerMoney (String receiver, int money){
        String inSql = "update user_account set money = money + ? where username = ?";
        this.getJdbcTemplate().update(inSql, money,receiver);
    }
}

3、测试代码

public class Tx_Test_02 {
    @Test
    public void test1 (){
        String xmlPath = "spring-jdbc-tx-02.xml";
        ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(xmlPath);
        UserAccountService01 accountService = (UserAccountService01)
                                    context.getBean("proxyAccountService");
        accountService.remittance("jack","tom",1000);
    }
}

四、XML配置事务

首先配置事务管理器,然后配置事务属性,最后基于AOP编程配置事务切入点。

1、核心配置

<!-- 配置事物管理器 -->
<bean id="txManager"
      class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
    <property name="dataSource" ref="dataSource" />
</bean>
<!-- 配置转账接口 -->
<bean id="userAccountService01"
      class="com.spring.mvc.service.impl.UserAccountServiceImpl01">
    <property name="jdbcTemplate" ref="jdbcTemplate" />
</bean>
<!-- 配置事物详情 -->
<tx:advice id="txAdvice" transaction-manager="txManager">
    <tx:attributes>
        <tx:method name="remittance"
                   propagation="REQUIRED"
                   isolation="DEFAULT"/>
    </tx:attributes>
</tx:advice>
<!-- 事务切入点,基于AOP编程 -->
<aop:config>
    <aop:advisor
         advice-ref="txAdvice"
         pointcut="execution(* com.spring.mvc.service.UserAccountService01.*(..))"/>
</aop:config>

五、基于事务注解

配置事务管理器,并启动事务注解的支持,在目标类或目标方法添加@Transactional核心注解即可。

1、核心配置

<!-- 配置事物管理器 -->
<bean id="txManager"
      class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
    <property name="dataSource" ref="dataSource" />
</bean>
<!-- 支持事务注解 -->
<tx:annotation-driven transaction-manager="txManager" />

2、注解用法

注解写在接口方法上,或者接口实现的方法上效果一样。

public interface UserAccountService02 {
    @Transactional(rollbackFor = Exception.class)
    void remittance(String remitTer, String receiver, int money) ;
}

六、源代码地址

GitHub·地址
https://github.com/cicadasmile/spring-mvc-parent
GitEE·地址
https://gitee.com/cicadasmile/spring-mvc-parent

原文地址:https://www.cnblogs.com/cicada-smile/p/11985733.html

时间: 2024-10-16 10:33:16

Spring 框架基础(05):事务管理机制,和实现方式的相关文章

Spring Transaction + MyBatis SqlSession事务管理机制研究学习

线上的系统中,使用的是Spring+Mybatis+Mysql搭建的框架,由于客户需要,最近一直在对性能提升部分进行考虑,主要是涉及Mysql的一些重要参数的配置学习,以及Spring事务管理机制的学习,因为通过观察服务器日志,发现在这两部分的时候耗时比较严重,特别是进行mysql事务提交的时候,项目源码中使用了Spring的声明式事务,即通过@Transactional注解来控制事务的开启与提交,这两天看了一些关于Spring Transaction事务的一些文章,也debug了源码,总算有点

12 Spring框架 SpringDAO的事务管理

上一节我们说过Spring对DAO的两个支持分为两个知识点,一个是jdbc模板,另一个是事务管理. 事务是数据库中的概念,但是在一般情况下我们需要将事务提到业务层次,这样能够使得业务具有事务的特性,来管理业务. 例如:在银行的转账系统中,张三转账给李四,需要完成从张三的账户上扣取指定金额并加到李四的账户上,这样一个过程需要具有原子性,即要成功都成功,要失败都失败.转账的过程即两个对账户更新,需要将事务提升到业务层次,使得两个操作具有原子性! 对以上的实现,Spring的API中有两个常用的接口我

[转]Spring3核心技术之事务管理机制

原文地址:http://chouyi.iteye.com/blog/1675199 Spring对事务的解决办法其实分为2种:编程式实现事务,AOP配置声明式解决方案. http://jinnianshilongnian.iteye.com/blog/1496953 Spring提供了许多内置事务管理器实现,常用的有以下几种: DataSourceTransactionManager:位于org.springframework.jdbc.datasource包中,数据源事务管理器,提供对单个ja

全面分析 Spring 的编程式事务管理及声明式事务管理--转

开始之前 关于本教程 本教程将深入讲解 Spring 简单而强大的事务管理功能,包括编程式事务和声明式事务.通过对本教程的学习,您将能够理解 Spring 事务管理的本质,并灵活运用之. 先决条件 本教程假定您已经掌握了 Java 基础知识,并对 Spring 有一定了解.您还需要具备基本的事务管理的知识,比如:事务的定义,隔离级别的概念,等等.本文将直接使用这些概念而不做详细解释.另外,您最好掌握数据库的基础知识,虽然这不是必须. 系统需求 要试验这份教程中的工具和示例,硬件配置需求为:至少带

spring3-spring的事务管理机制

1. Spring的事务管理机制 Spring事务管理高层抽象主要包括3个接口,Spring的事务主要是由他们共同完成的: PlatformTransactionManager:事务管理器-主要用于平台相关事务的管理 TransactionDefinition: 事务定义信息(隔离.传播.超时.只读)-通过配置如何进行事务管理. TransactionStatus:事务具体运行状态-事务管理过程中,每个时间点事务的状态信息. 1.1. PlatformTransactionManager事务管理

分析 Spring 的编程式事务管理及声明式事务管理(转)

开始之前 关于本教程 本教程将深入讲解 Spring 简单而强大的事务管理功能,包括编程式事务和声明式事务.通过对本教程的学习,您将能够理解 Spring 事务管理的本质,并灵活运用之. 先决条件 本教程假定您已经掌握了 Java 基础知识,并对 Spring 有一定了解.您还需要具备基本的事务管理的知识,比如:事务的定义,隔离级别的概念,等等.本文将直接使用这些概念而不做详细解释.另外,您最好掌握数据库的基础知识,虽然这不是必须. 系统需求 要试验这份教程中的工具和示例,硬件配置需求为:至少带

Spring 的编程式事务管理及声明式事务管理

本文将深入讲解 Spring 简单而强大的事务管理功能,包括编程式事务和声明式事务.通过对本教程的学习,您将能够理解 Spring 事务管理的本质,并灵活运用之. Spring 事务属性分析 事务管理对于企业应用而言至关重要.它保证了用户的每一次操作都是可靠的,即便出现了异常的访问情况,也不至于破坏后台数据的完整性.就像银行的自助取款机,通常都能正常为客户服务,但是也难免遇到操作过程中机器突然出故障的情况,此时,事务就必须确保出故障前对账户的操作不生效,就像用户刚才完全没有使用过取款机一样,以保

Spring整合hibernate4:事务管理

Spring和Hibernate整合后,通过Hibernate API进行数据库操作时发现每次都要opensession,close,beginTransaction,commit,这些都是重复的工作,我们可以把事务管理部分交给spring框架完成. 配置事务(xml方式) 使用spring管理事务后在dao中不再需要调用beginTransaction和commit,也不需要调用session.close(),使用API  sessionFactory.getCurrentSession()来

Spring多数据源分布式事务管理/springmvc+spring+atomikos[jta]+druid+mybatis

项目进行读写分离及分库分表,在一个业务中,在一个事务中处理时候将切换多个数据源,需要保证同一事务多个数据源数据的一致性.此处使用atomikos来实现:最后附源码: 1:spring3.0之后不再支持jtom[jta]了,第三方开源软件atomikos(http://www.atomikos.com/)来实现. 2:org.springframework.transaction.jta.JotmFactoryBean类,spring-tx-2.5.6.jar中有此类,spring-tx-3.0.