Spring事务-(1)

简介:
一、事务控制的基本知识
 
不管是什么事务,必须先对数据库的事务概念有个明确认识才行。首先先简单介绍下数据库的事务。
 
事务的概念:事务是一组原子性操作的工作单元,这组工作单元要么执行成功,要么不成功。事务有四个属性--原子性、一致性、独立性和持久性(CAID),所有这些方面都是依靠事务资源去维护。
 
事务隔离:SQL 标准用三个必须在并行的事务之间避免的现象定义了四个级别的事务隔离。 这些不希望发生的现象是:
 
脏读(dirty reads)
一个事务读取了另一个未提交的并行事务写的数据。
 
不可重复读(non-repeatable reads)
一个事务重新读取前面读取过的数据, 发现该数据已经被另一个已提交的事务修改过。
 
幻读(phantom read)
一个事务重新执行一个查询,返回一套符合查询条件的行, 发现这些行因为其他最近提交的事务而发生了改变。
 
 
这四种隔离级别和对应的行为如下表:
 
隔离级别 脏读(Dirty Read) 不可重复读(NonRepeatable Read) 幻读(Phantom Read)
读未提交(Read uncommitted) 可能 可能 可能
读已提交(Read committed) 不可能 可能 可能
可重复读(Repeatable read) 不可能 不可能 可能
可串行化(Serializable ) 不可能 不可能 不可能
 
Spring事务包中的TransactionDefinition接口有对应的隔离级别的定义。高清楚以上的概念,才能更好理解Spring的事务管理。
 
二、从编程的角度认识事务
 
和数据库事务概念几乎完全一样:事务是一种机制,把组成的多个操作视为一个操作单元进行处理,这个单元要么全部执行成功,要么全部不执行。在事务中,涉及的操作可能依赖于很多不同的数据库和服务器。
 
从程序角度考虑,事务可以分为两大类:一种是本地事务,一种是全局事务(也叫分布式事务)。
 
本地事务:是针对某个独立的事务资源(如JDBC)操作的事务。
全局事务:是协同或横跨多个资源(如JDBC连接、数据库等)操作的事务(上下文),多个资源协作是由事务管理器来完成的。
 
事务源:是可以绑定事务操作的资源。事务的概念最初来自数据库的操作,事务的资源也仅限于数据库。但编程中的事务,事务源很广泛,不但可以包含数据库,还可以包含打印机等。
 
本地事务和全局事务有很大的区别:
 
全局事务的控制非常复杂,全局事务使用两阶段提交协议(2PC)来提交资源源的变化。阶段一请求所有资源准备实现改变;阶段二请求做实际的改变。

全局事务ID(XID)是用于跟踪所有分布式事务相关的改变。全局事务的实现需要由专门的应用服务器或者容器去实现。在Java中,可以借助实现了Java Transaction API的库来进行全局事务控制。
 
JDBC与JTA
 
JDBC是Java database connectivity 的缩写,意思是Java数据库连接。一般本地事务是与一个数据库连接相关的,因此Java中常称本地事务为JDBC事务。JDBC本身提供了简单的本地事务控制,可以满足针对一个JDBC连接事务的需求。
 
JTA是Java Transaction API的缩写,意思是Java事务API,这是一种组复杂事务控制接口,这组接口作为J2EE规范暴露给容器开发商,一般都由J2EE容器来实现。Spring很牛,也实现了这组API,使得任何应用使用JTA事务变得更容易。
 
 
三、认识Spring的事务包的API
 
 
Spring对事务的控制的API全部位于org.springframework.transaction包下面,其中出去异常定义的类外,仅有四个接口,这四个接口是Spring操作事务的核心,下面一一介绍:
 
org.springframework.transaction
 
Interfaces 
        PlatformTransactionManager
        SavepointManager
        TransactionDefinition
        TransactionStatus
 
Exceptions 
        CannotCreateTransactionException
        HeuristicCompletionException
        IllegalTransactionStateException
        InvalidIsolationLevelException
        InvalidTimeoutException
        NestedTransactionNotSupportedException
        NoTransactionException
        TransactionException
        TransactionSuspensionNotSupportedException
        TransactionSystemException
        TransactionTimedOutException
        TransactionUsageException
        UnexpectedRollbackException
 
要搞明白Spring事务控制的原理,必须理解上面四个接口的含义,下面一一介绍之。
 
1、PlatformTransactionManager
 
是一个事务管理平台,该接口有许多具体的事务实现类,例如DataSourceTransactionManager, HibernateTransactionManager, JdoTransactionManager, JmsTransactionManager, JpaTransactionManager, JtaTransactionManager, TopLinkTransactionManager, WebLogicJtaTransactionManager 等等,通过实现此接口,Spring可以管理任何实现了这些接口的事务。开发人员也可以使用统一的编程模型来控制管理事务。此接口中有三个方法:
 
 void commit(TransactionStatus status)
          Commit the given transaction, with regard to its status.
          监视事务状态,并提交一个事务。
 TransactionStatus getTransaction(TransactionDefinition definition)
          Return a currently active transaction or create a new one, according to the specified propagation behavior.
          根据事务的隔离级别和传播行为,返回当前活动的事务或者产生一个新的事务。
 
 void rollback(TransactionStatus status)
          Roll back the given transaction.
          回滚给定的事务。
 
 
2、SavepointManager
 
事务回滚点管理接口,提供创建、释放回滚点,或者回滚到指定的回滚点。
 
 方法摘要:
 Object createSavepoint()
          Create a new savepoint.
          创建一个新的回滚点。
 void releaseSavepoint(Object savepoint)
          Explicitly release the given savepoint.
          释放一个给定的回滚点。
 void rollbackToSavepoint(Object savepoint)
          Roll back to the given savepoint.
          回滚到给定的回滚点。
 
 
3、TransactionDefinition
 
这个接口的作用就是定义事务的名称、隔离级别、传播行为、超时时间长短、只读属性等。
 
字段摘要:
(因为是接口,里面都是int常量,即public static final类型的,很多,我就只写常量的名字和含义)
这些接口分两组,分别是事务隔离级别和事务传播行为。
 
//事务隔离级别(数据库级别的知识)
TransactionDefinition.ISOLATION_DEFAULT
使用底层数据库默认隔离级别。
 
TransactionDefinition.ISOLATION_READ_UNCOMMITTED 读未提交
最低隔离等级,允许事务读取其他并行的事务还没有提交的数据,会发生脏读(dirty reads)、不可重复读(non-repeatable reads)、幻读(phantom read)等问题。
 
TransactionDefinition.ISOLATION_READ_COMMITTED 读已提交
允许事务读取其他并行的事务已经提交的数据,可以防止脏读问题。
 
TransactionDefinition.ISOLATION_REPEATABLE_READ 可重复读
保证了一个事务不会修改已经由另一个事务读取但未提交(回滚)的数据。
 
TransactionDefinition.ISOLATION_SERIALIZABLE 可串行化
所有事务都严格隔离,各个事务顺序执行。很容易发生死锁。
 
//事务传播行为
TransactionDefinition.PROPAGATION_REQUIRED
支持现有的事务,如果没有则新建一个事务。
 
TransactionDefinition.PROPAGATION_SUPPORTS
支持现有的事务,如果没有则以非事务状态运行。
 
TransactionDefinition.PROPAGATION_MANDATORY
支持现有事务,如果没有则抛出异常。
 
TransactionDefinition.PROPAGATION_REQUIRES_NEW
总是发起一个新事务。如果当前已存在一个事务,则将其挂起。
 
TransactionDefinition.PROPAGATION_NOT_SUPPORTED
不支持事务,总是以非事务状态运行,如果当前存在一个事务,则将其挂起。
 
TransactionDefinition.PROPAGATION_NEVER
不支持事务,总是以非事务状态运行,如果当前存在一个事务,则抛出异常。
 
TransactionDefinition.PROPAGATION_NESTED
如果石阡已经存在一个事务,则以嵌套事务的方式运行,如果当前没有事务,则创建一个新事务。
 
 方法摘要:
 int getIsolationLevel()
          Return the isolation level.
          返回事务的隔离级别。
 String getName()
          Return the name of this transaction.
          返回事务的名字。
 int getPropagationBehavior()
          Return the propagation behavior.
          返回事务的是传播行为。
 int getTimeout()
          Return the transaction timeout.
          返回事务的超时时间。
 boolean isReadOnly()
          Return whether to optimize as read-only transaction.
          返回是否(优化为)只读属性。
 
 
4、TransactionStatus
 
这个接口的作用就是获取事务的状态(回滚点、是否完成、是否新事物、是否回滚)属性,还可以进行事务rollback-only的设置。
 
方法摘要:
 boolean hasSavepoint()
          Return whether this transaction internally carries a savepoint, i.e. has been created as nested transaction based on a savepoint.
          判断这个事务是否有一个内在的回滚点(savepoint),即创建为基于回滚点的嵌套事务。
 boolean isCompleted()
          Return whether this transaction is completed, that is, has already been committed or rolled back.
          判断这个事务是否完成,也就是已经提交或者回滚。
 boolean isNewTransaction()
          Return if the transaction is new, else participating in an existing transaction.
          判断一个事物是否为新事务,或者是这个事务参与到一个已经存在的事务里面。
 boolean isRollbackOnly()
          Return if the transaction has been set rollback-only.
          判断这个事务是否已经设置了rollback-only。
 void setRollbackOnly()
          Set the transaction rollback-only.
          设置这个事务rollback-only。
 
 
本人的E文不好,是参考原API文档翻译的,部分地方参考了Pro Spring的内容。如果你觉得对翻译的部分有更准确的理解,可以留言发给我。
 
Spring事务是Spring应用非常重要的一个方面,内容很多,暂时先写到此,周末愉快!!!
 
-----------------------续
使用Spring编程式事务管理时,一般步骤如下:
1、从Spring容器中获取PlatformTransactionManager实例。
2、定义TransactionDefinition并设置好事务的隔离级别和传播方式。
3、通过PlatformTransactionManager.getTransaction()开始一个事务,并获得TransactionStatus对象。
4、运行需要在事务环境下执行的代码并捕获异常。
5、如果有异常发生,将TransactionStatus设置为setRollbackOnly(),表示要回滚事务。
6、调用PlatformTransactionManager.commit(TransactionStatus)方法提交事务,Spring根据TransactionStatus的状态决定如何提交事务。如果TransactionStatus设置为setRollbackOnly(),则回滚事务,否则提交


本文转自 leizhimin 51CTO博客,原文链接:http://blog.51cto.com/lavasoft/73567,如需转载请自行联系原作者
相关文章
|
8月前
|
SQL Java 关系型数据库
Spring事务传播机制:7种姿势教你玩转"事务接力赛"
事务传播机制是Spring框架中用于管理事务行为的重要概念,它决定了在方法调用时事务如何传递与执行。通过7种传播行为,开发者可以灵活控制事务边界,适应不同业务场景。例如:REQUIRED默认加入或新建事务,REQUIRES_NEW独立开启新事务,NESTED支持嵌套回滚等。合理使用传播机制不仅能保障数据一致性,还能提升系统性能与健壮性。掌握这“七种人格”,才能在复杂业务中游刃有余。
|
Java Spring
Spring中事务失效的场景
因为Spring事务是基于代理来实现的,所以某个加了@Transactional的⽅法只有是被代理对象调⽤时, 那么这个注解才会⽣效 , 如果使用的是被代理对象调用, 那么@Transactional会失效 同时如果某个⽅法是private的,那么@Transactional也会失效,因为底层cglib是基于⽗⼦类来实现 的,⼦类是不能重载⽗类的private⽅法的,所以⽆法很好的利⽤代理,也会导致@Transactianal失效 如果在业务中对异常进行了捕获处理 , 出现异常后Spring框架无法感知到异常, @Transactional也会失效
|
Java 关系型数据库 数据库
微服务——SpringBoot使用归纳——Spring Boot事务配置管理——常见问题总结
本文总结了Spring Boot中使用事务的常见问题,虽然通过`@Transactional`注解可以轻松实现事务管理,但在实际项目中仍有许多潜在坑点。文章详细分析了三个典型问题:1) 异常未被捕获导致事务未回滚,需明确指定`rollbackFor`属性;2) 异常被try-catch“吃掉”,应避免在事务方法中直接处理异常;3) 事务范围与锁范围不一致引发并发问题,建议调整锁策略以覆盖事务范围。这些问题看似简单,但一旦发生,排查难度较大,因此开发时需格外留意。最后,文章提供了课程源代码下载地址,供读者实践参考。
388 0
|
Java 关系型数据库 数据库
微服务——SpringBoot使用归纳——Spring Boot事务配置管理——Spring Boot 事务配置
本文介绍了 Spring Boot 中的事务配置与使用方法。首先需要导入 MySQL 依赖,Spring Boot 会自动注入 `DataSourceTransactionManager`,无需额外配置即可通过 `@Transactional` 注解实现事务管理。接着通过创建一个用户插入功能的示例,展示了如何在 Service 层手动抛出异常以测试事务回滚机制。测试结果表明,数据库中未新增记录,证明事务已成功回滚。此过程简单高效,适合日常开发需求。
1767 0
|
Java 数据库 微服务
微服务——SpringBoot使用归纳——Spring Boot事务配置管理——事务相关
本文介绍Spring Boot事务配置管理,阐述事务在企业应用开发中的重要性。事务确保数据操作可靠,任一异常均可回滚至初始状态,如转账、购票等场景需全流程执行成功才算完成。同时,事务管理在Spring Boot的service层广泛应用,但根据实际需求也可能存在无需事务的情况,例如独立数据插入操作。
336 0
|
9月前
|
Java 关系型数据库 数据库
深度剖析【Spring】事务:万字详解,彻底掌握传播机制与事务原理
在Java开发中,Spring框架通过事务管理机制,帮我们轻松实现了这种“承诺”。它不仅封装了底层复杂的事务控制逻辑(比如手动开启、提交、回滚事务),还提供了灵活的配置方式,让开发者能专注于业务逻辑,而不用纠结于事务细节。
1123 1
|
12月前
|
人工智能 Java 数据库连接
Spring事务失效场景
本文深入探讨了Spring框架中事务管理可能失效的几种常见场景及解决方案,包括事务方法访问级别不当、方法内部自调用、错误的异常处理、事务管理器或数据源配置错误、数据库不支持事务以及不合理的事务传播行为或隔离级别。通过合理配置和正确使用`@Transactional`注解,开发者可以有效避免这些问题,确保应用的数据一致性和完整性。
1005 10
|
11月前
|
Java 关系型数据库 MySQL
【Spring】【事务】初学者直呼学会了的Spring事务入门
本文深入解析了Spring事务的核心概念与使用方法。Spring事务是一种数据库事务管理机制,通过确保操作的原子性、一致性、隔离性和持久性(ACID),维护数据完整性。文章详细讲解了声明式事务(@Transactional注解)和编程式事务(TransactionTemplate、PlatformTransactionManager)的区别与用法,并探讨了事务传播行为(如REQUIRED、REQUIRES_NEW等)及隔离级别(如READ_COMMITTED、REPEATABLE_READ)。
754 1
|
SQL Java 数据库连接
Spring中的事务是如何实现的
1. Spring事务底层是基于数据库事务和AOP机制的 2. ⾸先对于使⽤了@Transactional注解的Bean,Spring会创建⼀个代理对象作为Bean 3. 当调⽤代理对象的⽅法时,会先判断该⽅法上是否加了@Transactional注解 4. 如果加了,那么则利⽤事务管理器创建⼀个数据库连接 5. 并且修改数据库连接的autocommit属性为false,禁⽌此连接的⾃动提交,这是实现Spring事务⾮ 常重要的⼀步 6. 然后执⾏当前⽅法,⽅法中会执⾏sql 7. 执⾏完当前⽅法后,如果没有出现异常就直接提交事务 8. 如果出现了异常,并且这个异常是需要回滚的就会回滚事务
|
JavaScript Java 开发者
Spring事务失效,常见的情况有哪些?
本文总结了Spring事务失效的7种常见情况,包括未启用事务管理功能、方法非public类型、数据源未配置事务管理器、自身调用问题、异常类型错误、异常被吞以及业务和事务代码不在同一线程中。同时提供了两种快速定位事务相关Bug的方法:通过查看日志(设置为debug模式)或调试代码(在TransactionInterceptor的invoke方法中设置断点)。文章帮助开发者更好地理解和解决Spring事务中的问题。
677 7