返回介绍

5.1 Spring 事务

发布于 2025-04-26 13:53:50 字数 3106 浏览 0 评论 0 收藏

5.1.1 Spring 事务介绍

事务管理是企业级应用程序开发中必不可少的技术,用来确保数据的完整性和一致性。事务有四大特性(ACID):原子性(Atomicity)、一致性(Consistency)、隔离性(Isolation)和持久性(Durability)。作为企业级应用程序框架,Spring 在不同的事务管理 API 上定义了一个抽象层,而应用程序开发人员不必了解底层的事务管理 API,就可以使用 Spring 的事务管理机制。

Spring 既支持编程式事务管理(也称编码式事务),又支持声明式事务管理。编程式事务管理是指将事务管理代码嵌入业务方法中来控制事务的提交和回滚。在编程式事务中,必须在每个业务操作中包含额外的事务管理代码。声明式事务管理是指将事务管理代码从业务方法中分离出来,以声明的方式来实现事务管理。在大多数情况下,声明式事务管理比编程式事务管理更好用。Spring 通过 Spring AOP 框架支持声明式事务管理。

数据访问的技术很多,如 JDBC、JPA、Hibernate、分布式事务等。面对众多的数据访问技术,Spring 在不同的事务管理 API 上定义了一个抽象层 PlatformTransaction-Manager,应用程序开发人员不必了解底层的事务管理 API 就可以使用 Spring 的事务管理机制。

Spring 并不直接管理事务,而是提供了许多内置事务管理器实现,常用的有 DataSourceTransactionManager、JdoTransactionManager、JpaTransactionManager 以及 HibernateTransactionManager 等。

5.1.2 Spring 声名式事务

Spring 配置文件中关于事务配置总是由三部分组成,分别是 DataSource、TransactionManager 和代理机制。无论哪种配置方式,一般变化的只是代理机制部分,DataSource 和 TransactionManager 这两部分只会根据数据访问方式有所变化,比如使用 Hibernate 进行数据访问时,DataSource 实现为 SessionFactory,TransactionManager 的实现为 HibernateTransactionManager。

Spring 声明式事务配置提供 5 种方式,而基于 Annotation 的注解方式目前比较流行,所以这里只简单介绍基于注解方式配置 Spring 声明式事务。我们可以使用 @ Transactional 注解在类或者方法中表明该类或者方法需要事务支持,被注解的类或者方法被调用时,Spring 开启一个新的事务,当方法正常运行时,Spring 会提交这个事务。具体例子如下:

这里需要注意的是,@Transactional 注解来自 org.springframework.transaction. annotation。Spring 提供了 @EnableTransactionManagement 注解在配置类上来开启声明式事务的支持。使用 @EnableTransactionManagement 后,Spring 容器会自动扫描注解 @Transactional 的方法和类。

5.1.3 Spring 注解事务行为

当事务方法被另一个事务方法调用时,必须指定事务应该如何传播。例如,方法可能继续在现有事务中运行,也可能开启一个新事务,并在自己的事务中运行。事务的传播行为可以在 @Transactional 的属性中指定,Spring 定义了 7 种传播行为,具体如表 5-1 所示。

表 5-1 Spring 传播行为

隔离级别定义了一个事务可能受其他并发事务影响的程度。在典型的应用程序中,多个事务并发运行经常会操作相同的数据来完成各自的任务。并发虽然是必需的,可是会导致许多问题,并发事务所导致的问题可以分为以下三类。

(1)脏读(Dirty Read):脏读发生在一个事务读取了另一个事务改写但尚未提交的数据。如果改写在稍后被回滚了,那么第一个事务获取的数据就是无效的。

(2)不可重复读(Nonrepeatable Read):不可重复读发生在一个事务执行相同的查询两次或两次以上,但是每次都得到不同的数据时。通常是因为另一个并发事务在两次查询期间更新了数据。

(3)幻读(Phantom Read):幻读与不可重复读类似,发生在一个事务(T1)读取了几行数据,接着另一个并发事务(T2)插入了一些数据时。在随后的查询中,第一个事务(T1)就会发现多了一些原本不存在的记录。

针对这些问题,Spring 提供了 5 种事务的隔离级别,具体如表 5-2 所示。

表 5-2 Spring 隔离级别

@Transactional 可以通过 propagation 属性定义事务行为,属性值分别为 REQUIRED、SUPPORTS、MANDATORY、REQUIRES_NEW、NOT_SUPPORTED、NEVER 以及 NESTED,分别对应表 5-1 中的内容。可以通过 isolation 属性定义隔离级别,属性值分别为 DEFAULT、READ_UNCOMMITTED、READ_COMMITTED、REPEATABLE_ READ 以及 SERIALIZABLE。

还可以通过 timeout 属性设置事务过期时间,通过 readOnly 指定当前事务是否是只读事务,通过 RollbackFor(noRollbackFor)指定哪个或者哪些异常可以引起(或不可以引起)事务回滚。

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。