Spring声明式事务详解
发布日期:2021-06-30 12:23:25 浏览次数:2 分类:技术文章

本文共 4121 字,大约阅读时间需要 13 分钟。

1 事务管理

  • 提供的统一的API接口支持不同的资源
  • 提供声明式事务管理
  • 方便的与Spring框架集成
  • 多个资源的事务管理、同步

2 事务抽象

2.1 事务管理器 - PlatformTransactionManager

public interface PlatformTransactionManager {
TransactionStatus getTransaction(TransactionDefinition definition)throws TransactionException; void commit(TransactionStatus status) throws TransactionException; void rollback(TransactionStatus status) throws TransactionException;}

2.2 事务定义 - TransactionDefinition

public interface TransactionDefinition {
int getPropagationBehavior(); int getlsolationLevel(); String getName(); int getTimeout(); boolean isReadOnly();}

2.3 事务隔离机制

TransactionDefinition.ISOLATION_DEFAULTTransactionDefinition.ISOLATION_READ_COMMITTEDTransactionDefinition.ISOLATION_READ_UNCOMMITTEDTransactionDefinition.ISOLATION_REPEATABLE_READTransactionDefinition.ISOLATION_SERIALIZABLE

2.4 事务传播机制

TransactionDefinition接口定义了如下int 常量:

PROPAGATION_REQUIRED (Default)

支持当前事务; 如果不存在,请创建一个新的。事务定义的默认设置,并且定义了事务同步的作用域

PROPAGATION_SUPPORTS

支持当前事务; 如果不存在,则以非事务方式执行。

对于具有事务同步的事务管理器, PROPAGATION_SUPPORTS与根本没有事务略有不同,因为它定义了同步可能适用的事务范围。 结果,将为整个指定范围共享相同的资源(JDBC Connection ,Hibernate Session等)。
准确的行为取决于事务管理器的实际同步配置!
通常,请谨慎使用PROPAGATION_SUPPORTS ! 特别是,不要依赖PROPAGATION_SUPPORTS范围内的

  • PROPAGATION_REQUIRED
  • PROPAGATION_REQUIRES_NEW (这可能会在运行时导致同步冲突)

如果这种嵌套是不可避免的,请确保正确配置事务管理器(通常切换为“实际事务同步”)

PROPAGATION_MANDATORY

PROPAGATION_REQUIRES_NEW

PROPAGATION_NOT_SUPPORTED

不支持当前事务;而是始终以非事务方式执行。类似于同名的EJB事务属性。

实际的事务中止将无法在所有事务管理器中立即使用。 这尤其适用于org.springframework.transaction.jta.JtaTransactionManager ,它要求javax.transaction.TransactionManager对其可用(在标准Java EE中是特定于服务器的)。
事务同步在PROPAGATION_NOT_SUPPORTED作用域内不可用。 现有同步将被挂起并适时恢复

TransactionDefinition.PROPAGATION_NEVER

不支持当前事务;如果当前事务存在,则抛异常。类似于同名的EJB事务属性。事务同步在PROPAGATION_NEVER作用域内不可用

  • PROPAGATION_NESTEDED

  • REQUIRED

    适用于增删改

  • SUPPORTS

    适用于查询。

TransactionStatus

Spring提供了PlatformTransactionManager表示事务管理器,所有事务都由它管理。

而事务由TransactionStatus表示。

public interface TransactionStatus extends SavepointManager {
boolean isNewTransaction(); boolean hasSavepoint(); void setRollbackOnly(); boolean isRollbackOnly(); boolean isCompleted();}

如果手写事务代码,使用try…catch如下:

TransactionStatus tx = null;try {
// 开启事务: tx = txManager.getTransaction(new DefaultTransactionDefinition()); // 相关JDBC操作: jdbcTemplate.update("..."); jdbcTemplate.update("..."); // 提交事务: txManager.commit(tx);} catch (RuntimeException e) {
// 回滚事务: txManager.rollback(tx); throw e;}

为啥要抽象出PlatformTransactionManager和TransactionStatus?

JavaEE除了提供JDBC事务,还支持分布式事务JTA(Java Transaction API)。分布式事务是指多个数据源(比如多个数据库,多个消息系统)要在分布式环境下实现事务的时候,应该怎么实现。分布式事务实现起来非常复杂,简单说就是通过一个分布式事务管理器实现两阶段提交,但本身数据库事务就不快,基于数据库事务实现的分布式事务就慢得难以忍受,所以使用率不高。

Spring为了同时支持JDBC和JTA两种事务模型,就抽象出PlatformTransactionManager。

因为我们的代码只需要JDBC事务,因此,在AppConfig中,需要再定义一个PlatformTransactionManager对应的Bean,它的实际类型是DataSourceTransactionManager:

@Configuration@ComponentScan@PropertySource("jdbc.properties")public class AppConfig {
... @Bean PlatformTransactionManager createTxManager(@Autowired DataSource dataSource) {
return new DataSourceTransactionManager(dataSource); }}

3 代码实战

public OrderService {
@Autowire PlatformTransactionManager txManager void buyTicket(BuyTicketDTO dto) {
DefaultTransactionDefinition def = new DefaultTransactionDefinition(); def.setPropagationBehavior(TransactionDefinition.PROPAGATION REQUIRED); TransactionStatus status = txManager.getTransaction(def); try {
//执行业务代码 txManager.commit(status); } catch (Exception e) {
txManager.rollback(status); } } }

Transactional标签方式实现1

public OrderService {
@Transactonal void buyTicket(BuyTicketDTO dto) {
/ save order // finish customer pay // transfer tickets }}

Transactional标签方式实现2

public OrderServiceProxy {
void buyTicket(BuyTicketDTO dto) {
// get and begin transaction manager from context try{
orderServicelmpl.buyTicket(dto); // commit transaction } catch (Exceptione) {
// roolbback transaction }}
  • 执行原理流程图

PlatformTransactionManager常见实现

  • DataSourceTransactionManager
  • JpaTransactionManager
  • JmsTransactionManager
  • JtaTransactionManager

但使用声明式事务经常遇到问题:

  • 数据库连接耗尽
  • 处理中的问题(比如调用接口超时)

转载地址:https://javaedge.blog.csdn.net/article/details/104889206 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!

上一篇:git -modified: xxx目录没有被跟踪
下一篇:MySQL事务基础

发表评论

最新留言

第一次来,支持一个
[***.219.124.196]2024年04月26日 08时05分47秒

关于作者

    喝酒易醉,品茶养心,人生如梦,品茶悟道,何以解忧?唯有杜康!
-- 愿君每日到此一游!

推荐文章

【工具使用】CSDN编辑器markdown字体、颜色与字号的设置 2019-04-30
【NLP学习笔记】词共现矩阵 2019-04-30
【NLP学习笔记】NLP基础知识框架图 2019-04-30
【深度学习笔记】卷积的输入输出的通道、维度或尺寸变化过程 2019-04-30
【NLP学习笔记】训练集、验证集和测试集的概念及划分 2019-04-30
【NLP学习笔记】conda换源 2019-04-30
【深度学习笔记】常见的图像增强方法:scaling、rotating、flipping、random cropping 2019-04-30
【深度学习笔记】标准卷积 2019-04-30
【深度学习笔记】组卷积 2019-04-30
【深度学习笔记】循环神经网络和递归神经网络区别 2019-04-30
【学习笔记】英文科技论文常见英语句式积累 2019-04-30
【深度学习笔记】PixelShuffle 2019-04-30
【python3学习笔记】斜杠和双斜杠运算符的区别 2019-04-30
【深度学习笔记】torch.nn.Sequential(* args) 与 torch.nn.Module 2019-04-30
【深度学习笔记】用torch.nn.Sequential()搭建神经网络模型 2019-04-30
【深度学习笔记】用torch.nn.ModuleList搭建神经网络 2019-04-30
【解决错误】AttributeError: module ‘scipy.misc‘ has no attribute ‘imread‘ 2019-04-30
【解决错误】复现RCAN的时候遇到了ImportError: cannot import name ‘_update_worker_pids’ from ‘torch._C’ 2019-04-30
【解决错误】ModuleNotFoundError: No module named ‘skimage‘ 2019-04-30
【深度学习笔记】pytorch的点乘(dot product) 2019-04-30