Spring:事务

摘要

本文摘抄了Spring事务相关的一些理论,主要讲述事务的特性、事务的传播行为、事务的隔离规则。

关键词:事务特性,事务传播事务隔离

一、什么是事务

事务是用来保证数据的完整性和一致性,正如金钱转账,金钱总数不会增加也不会减少。

数据库 事务管理有四个特性(ACID):

特性 描述
原子性(Atomicity) 事务作为一个整体被执行,要么全部被执行,要么都不执行。
一致性(Consistency) 事务应确保数据的状态从一个一致状态转变为另一个一致状态,数据不应该被破坏。
隔离性(Isolation) 多个事务并发执行时,一个事务的执行不应影响其他事务的执行。
持久性(Durability) 已被提交的事务对数据的修改应该永久性的。

二、Spring事务管理器

1. 事务管理接口

Spring中定义了事务管理的总接口PlatformTransactionManager,该接口定义了以下几个接口来管理事务:

  • getTransaction() - 获取事务状态(TransactionStatus),该事务由(TransactionDefinition定义)
  • commit() - 提交事务
  • rollback() - 回滚事务

Spring不直接管理事务,而是提供一个事务管理接口,由其他平台(如JDBC、Hibernate)自己实现事务管理。

几个具体的事务:

事务名称 管理器类 说明
JDBC事务 org.springframework.jdbc.datasource.DataSourceTransactionManager 通过调用java.sql.Connection来管理事务
Hibernate org.springframework.orm.hibernate3.HibernateTransactionManager 事务管理由org.hibernate.Transaction对象负责
Java持久化API事务(JPA) org.springframework.orm.jpa.JpaTransactionManager JpaTransactionManager与由工厂(javax.persistence.EntityManagerFactory)所产生的JPA EntityManager合作来构建事务
Java原生API事务 org.springframework.transaction.jta.JtaTransactionManager JtaTransactionManager将事务管理的责任委托给javax.transaction.UserTransaction和javax.transaction.TransactionManager对象(允许在多个数据库之间管理多个事务

关于JTA,参考Java中的事务——JDBC事务和JTA事务

(Spring事务管理器)

2. 事务管理与AOP

Spring通过AOP拦截所有需要事务管理的业务处理方法。

三、Spring事务属性

Spring事务有几个属性,TransactionDefinition接口可以体现出来:

public interface TransactionDefinition {
    // 事务传播行为定义
    int PROPAGATION_REQUIRED = 0;
    int PROPAGATION_SUPPORTS = 1;
    int PROPAGATION_MANDATORY = 2;
    int PROPAGATION_REQUIRES_NEW = 3;
    int PROPAGATION_NOT_SUPPORTED = 4;
    int PROPAGATION_NEVER = 5;
    int PROPAGATION_NESTED = 6;
    // 事务隔离级别定义
    int ISOLATION_DEFAULT = -1;
    int ISOLATION_READ_UNCOMMITTED = Connection.TRANSACTION_READ_UNCOMMITTED;
    int ISOLATION_READ_COMMITTED = Connection.TRANSACTION_READ_COMMITTED;
    int ISOLATION_REPEATABLE_READ = Connection.TRANSACTION_REPEATABLE_READ;
    int ISOLATION_SERIALIZABLE = Connection.TRANSACTION_SERIALIZABLE;
    // 默认超时时间
    int TIMEOUT_DEFAULT = -1;

    // 获取事务传播行为
    int getPropagationBehavior();
    // 获取事务隔离级别
    int getIsolationLevel();
    // 获取事务超时时间
    int getTimeout();
    // 获取事务是否只读
    boolean isReadOnly();
    // 获取事务名字
    String getName();
}

接口的定义加上回滚规则,事务可以有以下五个基本配置:事务传播行为、事务隔离级别、事务超时、事务只读、回滚规则

1. 传播行为

所谓传播行为(propagation behavior)指一个事务方法被另一个事务方法调用时,事务应该如何处理。被调用的方法可能在现有事务中运行,或者启动一个新的事务,在自己事务内运行。

传播行为 含义 解释
PROPAGATION_REQUIRED 表示当前方法必须运行在事务中。如果当前事务存在,方法将会在该事务中运行。否则,会启动一个新的事务 有且只有一个事务
PROPAGATION_SUPPORTS 表示当前方法不需要事务上下文,但是如果存在当前事务的话,那么该方法会在这个事务中运行 如果方法单独调用则是非事务执行,如果方法被另一个有事务的方法调用,被调用方法则加入事务
PROPAGATION_MANDATORY 表示该方法必须在事务中运行,如果当前事务不存在,则会抛出一个异常 如果单独非事务调用会抛异常,必须被其它事务方法调用,加入到事务中。
PROPAGATION_REQUIRED_NEW 表示当前方法必须运行在它自己的事务中。一个新的事务将被启动。如果存在当前事务,在该方法执行期间,当前事务会被挂起。如果使用JTATransactionManager的话,则需要访问TransactionManager 总是开启一个新的事务,原调用事务存在的话会被挂起,直至事务完成。
PROPAGATION_NOT_SUPPORTED 表示该方法不应该运行在事务中。如果存在当前事务,在该方法运行期间,当前事务将被挂起。如果使用JTATransactionManager的话,则需要访问TransactionManager 总是非事务地执行该方法,如果调用事务存在的话会被挂起,直至方法执行完成
PROPAGATION_NEVER 表示当前方法不应该运行在事务上下文中。如果当前正有一个事务在运行,则会抛出异常 总是非事务性执行方法,否则抛出异常
PROPAGATION_NESTED 表示如果当前已经存在一个事务,那么该方法将会在嵌套事务中运行。嵌套的事务可以独立于当前事务进行单独地提交或回滚。如果当前事务不存在,那么其行为与PROPAGATION_REQUIRED一样。注意各厂商对这种传播行为的支持是有所差异的。可以参考资源管理器的文档来确认它们是否支持嵌套事务 嵌套事务一个非常重要的概念就是内层事务依赖于外层事务。外层事务失败时,会回滚内层事务所做的动作。而内层事务操作失败并不会引起外层事务的回滚。

2. 隔离规则

事务的执行会存在并发的,隔离级别定义了一个事务受其它并发事务影响的程度。

有两个表格:

并发事务引起的问题

问题 定义 出现原因
脏读 读到无效的数据 当一个事务读取了另一个事务修改但未提交的数据,如果修改回滚,则事务读取了无效的数据。
不可重复读 同一个事务中两次相同查询中,读取到不同的数据 一个事务两次查询期间,另一个并发事务对数据进行了更新。
幻读 同一个事务在两次相同的查询中,读取到不同记录数的数据 一个事务两次查询期间,另一个并发事务进行了数据新增或删除。

隔离级别

隔离级别 说明 并发事务可能引起的问题
ISOLATION_DEFAULT 使用后端数据库默认的隔离级别 具体情况具体分析
ISOLATION_READ_UNCOMMITTED 最低的隔离级别,允许读取尚未提交的数据变更 脏读、不可重复读、幻读
ISOLATION_READ_COMMITTED 允许读取并发事务已经提交的数据 不可重复读、幻读
ISOLATION_REPEATABLE_READ 对同一字段的多次读取结果一致,除非字段被本事务修改 幻读
ISOLATION_SERIALIZABLE 最高的隔离级别,完全服从ACID原则,通常通过锁表实现(最慢)

3. 事务超时

给定事务一个超时时间,如果特定时间事务没有执行完毕,事务会自动回滚。

4. 是否只读?

设置了只读事务,那么在此事务执行过程中,其它事务对数据库的修改对于该事务来说是透明的,即看不到其它事务修改后的数据。这通常用于执行多次查询来统计信息时,能够保证数据的整体一致性

5. 回滚规则

回滚规则定义了哪些异常,事务会进行回滚。默认情况下,事务只有遇到运行时异常才会回滚,而在遇到检查型异常时不会回滚。

四、Spring事务管理形式

1. 编程式事务

使用TransactionTemplate或PlatformTransactionManager

TransactionTemplate tt = new TransactionTemplate();
tt.execute(status -> {
    // 执行操作
    doSth();
    // 返回操作结果
    return obj;
});

2. 声明式事务

参考:Spring事务配置的五种方式

六、总结

  1. Spring定义了事务管理器的接口,具体实现由特定平台来实现;
  2. Spring事务有五个属性:事务传播行为、事务隔离级别、事务超时、事务只读、回滚规则;
  3. 传播行为:required、supports、mandatory、required_new、not_support、never、nested;
  4. 隔离级别:default、read_uncommited、read_committed、repeatable_read、serializable;

参考资料

  1. Spring事务管理(详解+实例)
  2. Spring 事务管理原理探究

原文地址:https://www.cnblogs.com/guanjianzhuo/p/9653119.html

时间: 2024-11-11 22:15:36

Spring:事务的相关文章

Spring事务管理(详解+实例)

写这篇博客之前我首先读了<Spring in action>,之后在网上看了一些关于Spring事务管理的文章,感觉都没有讲全,这里就将书上的和网上关于事务的知识总结一下,参考的文章如下: Spring事务机制详解 Spring事务配置的五种方式 Spring中的事务管理实例详解 1 初步理解 理解事务之前,先讲一个你日常生活中最常干的事:取钱. 比如你去ATM机取1000块钱,大体有两个步骤:首先输入密码金额,银行卡扣掉1000元钱:然后ATM出1000元钱.这两个步骤必须是要么都执行要么都

spring事务没回滚

最近遇见一个问题,用spring管理实务,在service层处理数据,保存数据时出现异常,但没有回滚,检查了一下,发现是因为我用try catch将异常进行捕获了,没有抛出导致的:默认spring事务只在发生未被捕获的 runtimeexcetpion时才回滚. 处理发法一:捕获异常后,新生成runtimeexcetpion: try { userDao.save(user); userDao.update(user); } catch (Exception e) { logger.info("

Spring事务管理

写这篇博客之前我首先读了<spring in action>,之后在网上看了一些关于Spring事务管理的文章,感觉都没有讲全,这里就将书上的和网上关于事务的知识总结一下,参考的文章如下: Spring事务机制详解 Spring事务配置的五种方式 Spring中的事务管理实例详解 1 初步理解 理解事务之前,先讲一个你日常生活中最常干的事:取钱. 比如你去ATM机取1000块钱,大体有两个步骤:首先输入密码金额,银行卡扣掉1000元钱:然后ATM出1000元钱.这两个步骤必须是要么都执行要么都

Spring事务

事务首先是一系列操作组成的工作单元,该工作单元内的操作是不可分割的,即要么所有操作都做,要么所有操作都不做 ACID 1.原子性(Atomicity)    即事务是不可分割的最小工作单元,事务内的操作要么全做,要么全不做2.一致性(Consistency)    在事务执行前数据库的数据处于正确的状态,而事务执行完成后数据库的数据还是处于正确的状态,即数据完整性约束没有被破坏    如银行转帐,A转帐给B,必须保证A的钱一定转给B,一定不会出现A的钱转了但B没收到,否则数据库的数据就处于不一致

深入理解 Spring 事务原理

一.事务的基本原理 Spring事务的本质其实就是数据库对事务的支持,没有数据库的事务支持,spring是无法提供事务功能的.对于纯JDBC操作数据库,想要用到事务,可以按照以下步骤进行: 获取连接 Connection con = DriverManager.getConnection() 开启事务con.setAutoCommit(true/false); 执行CRUD 提交事务/回滚事务 con.commit() / con.rollback(); 关闭连接 conn.close(); 使

spring事务声明的几种传播特性

最近遇到了一个spring事务导致的问题,所以写了几个小程序了解了一下事务的传播特性,下面分别举例子分别看看事务的传播特性. 事务的几种传播特性 1. PROPAGATION_REQUIRED: 如果存在一个事务,则支持当前事务.如果没有事务则开启 Java代码   /** * TransactionTestService     test1和test2配有事务(PROPAGATION_REQUIRED) */ public interface TransactionTestService {

Spring事务配置的五种方式

Spring事务配置的五种方式 前段时间对Spring的事务配置做了比较深入的研究,在此之间对Spring的事务配置虽说也配置过,但是一直没有一个清楚的认识.通过这次的学习发觉Spring的事务配置只要把思路理清,还是比较好掌握的. 总结如下: Spring配置文件中关于事务配置总是由三个组成部分,分别是DataSource.TransactionManager和代理机制这三部分,无论哪种配置方式,一般变化的只是代理机制这部分. DataSource.TransactionManager这两部分

spring事务管理-摘抄

原著网址 http://gcq04552015.iteye.com/blog/1666570 Spring是以代理的方式实现对事务的管理.我们在Action中所使用的Service对象,其实是代理对象的实例,并不是我们所写的Service 对象实例.既然是两个不同的对象,那为什么我们在Action中可以象使用Service对象一样的使用代理对象呢?为了说明问题,假设有个 Service类叫AService,它的Spring事务代理类为AProxyService,AService实现了一个接口 I

Spring 事务管理

<?xml version="1.0" encoding="UTF-8"?> <beans  xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:mvc="http://www.springframework.org/schema

Spring事务管理接口PlatformTransactionManager的实现类DataSourceTransactionManager

package org.springframework.jdbc.datasource; import java.sql.Connection; import java.sql.SQLException; import javax.sql.DataSource; import org.apache.commons.logging.Log; import org.springframework.beans.factory.InitializingBean; import org.springfra