干货!Spring事物传播特性隔离级别ACID及StringBoot编程式事务与声明式事务(1)

/**

  • (7)事物传播特性:
  • 如果当前事务存在,则在嵌套事务中执行,否则的行为类似于{@link #PROPAGATION_REQUIRED}。
  • 实际创建嵌套事务只适用于特定的事务管理器。
  • @see org.springframework.jdbc.datasource.DataSourceTransactionManager
    */
    int PROPAGATION_NESTED = 6;

/**

  • 隔离级别越高,越能保证数据的完整性和一致性,但是对并发性能的影响也越大。
  • 对于多数应用程序,可以优先考虑把数据库系统的隔离级别设为Read Committed。
  • 它能够避免脏读取,而且具有较好的并发性能。尽管它会导致不可重复读、幻读和第二类丢失更新这些并发问题,
  • 在可能出现这类问题的个别场合,可以由应用程序采用悲观锁或乐观锁来控制。
  • Spring中同时提供一个标识:ISOLATION_DEFAULT。表示使用后端数据库默认的隔离级别。
  • 大多数数据库默认的事务隔离级别是Read committed,比如Sql Server , Oracle。
  • MySQL的默认隔离级别是Repeatable read。
    /
    /
    *
  • 事务隔离级别
  • 使用底层数据存储的默认隔离级别。
  • 所有其他级别都对应于JDBC隔离级别。
  • @see java.sql.Connection
    */
    int ISOLATION_DEFAULT = -1;

/**

  • 事务隔离级别
  • 未提交读取(Read Uncommitted)
  • 允许脏读取,但不允许更新丢失。如果一个事务已经开始写数据,则另外一个事务则不允许同时进行写操作,
  • 但允许其他事务读此行数据。该隔离级别可以通过“排他写锁”实现。
  • @see java.sql.Connection#TRANSACTION_READ_UNCOMMITTED
    */
    int ISOLATION_READ_UNCOMMITTED = Connection.TRANSACTION_READ_UNCOMMITTED;

/**

  • 事务隔离级别
  • 已提交读取(Read Committed)
  • 允许不可重复读取,但不允许脏读取。这可以通过“瞬间共享读锁”和“排他写锁”实现。
  • 读取数据的事务允许其他事务继续访问该行数据,但是未提交的写事务将会禁止其他事务访问该行。
  • @see java.sql.Connection#TRANSACTION_READ_COMMITTED
    */
    int ISOLATION_READ_COMMITTED = Connection.TRANSACTION_READ_COMMITTED;

/**

  • 事务隔离级别
  • 可重复读取(Repeatable Read)
  • 禁止不可重复读取和脏读取,但是有时可能出现幻读数据。这可以通过“共享读锁”和“排他写锁”实现。
  • 读取数据的事务将会禁止写事务(但允许读事务),写事务则禁止任何其他事务。
  • @see java.sql.Connection#TRANSACTION_REPEATABLE_READ
    */
    int ISOLATION_REPEATABLE_READ = Connection.TRANSACTION_REPEATABLE_READ;

/**

  • 事务隔离级别
  • 序列化(Serializable) 提供严格的事务隔离。它要求事务序列化执行,事务只能一个接着一个地执行,不能并发执行。
  • 仅仅通过“行级锁”是无法实现事务序列化的,必须通过其他机制保证新插入的数据不会被刚执行查询操作的事务访问到。
  • @see java.sql.Connection#TRANSACTION_SERIALIZABLE
    /
    int ISOLATION_SERIALIZABLE = Connection.TRANSACTION_SERIALIZABLE;
    /
    *
    *使用基础事务系统的默认超时,如果不支持超时,则使用无。
    */
    int TIMEOUT_DEFAULT = -1;

/**

  • 返回传播行为。 必须返回在{@link TransactionDefinition} 此接口
  • 上定义的{@code PROPAGATION_XXX}常量之一。
  • @return 传播行为
  • @see #PROPAGATION_REQUIRED
  • @see org.springframework.transaction.support.TransactionSynchronizationManager#isActualTransactionActive()
    */
    int getPropagationBehavior();

/**

  • 返回隔离级别。
  • 必须返回在{@link TransactionDefinition }接口上定义的{@code ISOLATION_XXX}常量之一。
  • 这些常量被设计成与{@link java.sql.Connection}上相同常量的值相匹配.
  • 专门设计用于{@link #PROPAGATION_REQUIRED}或{@link #PROPAGATION_REQUIRES_NEW},
  • 因为它只适用于新启动的事务。如果您希望在参与具有不同隔离级别的现有事务时拒绝隔离级别声明,
  • 请考虑将事务管理器上的“validateExistingTransactions”标志切换为“true”。
  • 请注意,不支持自定义隔离级别的事务管理器在被赋予{@link #ISOLATION_DEFAULT}以外的任何其他级别时,都会引发异常。
  • @return 隔离级别
  • @see #ISOLATION_DEFAULT
  • @see org.springframework.transaction.support.AbstractPlatformTransactionManager#setValidateExistingTransaction
    */
    int getIsolationLevel();

/**

  • 返回事务超时。
  • 必须返回秒数,或{@link #TIMEOUT_DEFAULT}。
  • 专为{@link #PROPAGATION_REQUIRED}或{@link #PROPAGATION_REQUIRES_NEW}使用而设计,因为它仅适用于新启动的事务
  • 请注意,不支持超时的事务管理器在给定{@link #TIMEOUT_DEFAULT}以外的任何其他超时时,将引发异常。
  • @return 事务超时
    */
    int getTimeout();

/**

  • 返回是否作为只读事务进行优化。
  • 返回是否优化为只读事务。
  • 只读标志适用于任何事务上下文,无论是由实际资源事务支持
  • ({@link #PROPAGATION_REQUIRED} / {@link #PROPAGATION_REQUIRES_NEW})
  • 还是在资源级别以非事务方式操作({@link #PROPAGATION_SUPPORTS})。
  • 在后一种情况下,该标志仅适用于应用程序内的托管资源,例如Hibernate {@code Session}。
  • 这只是实际交易子系统的提示。 不一定</ i>会导致写访问尝试失败。
  • 当请求只读事务时,无法解释只读提示的事务管理器将不</ i>抛出异常。
  • @return 如果事务将被优化为只读,则{@code true}
  • @see org.springframework.transaction.support.TransactionSynchronization#beforeCommit(boolean)
  • @see org.springframework.transaction.support.TransactionSynchronizationManager#isCurrentTransactionReadOnly()
    */
    boolean isReadOnly();

/**

  • 返回此事务的名称。可以是{@code null}。
  • 这将用作要在事务监视器中显示的事务名称(如WebLogic)。
  • 对于Spring的声明性事务,公开的名称将是{@code 完全限定类名+“.”+方法名}(默认情况下)。
  • @return 事务的名称
  • @see org.springframework.transaction.interceptor.TransactionAspectSupport
  • @see org.springframework.transaction.support.TransactionSynchronizationManager#getCurrentTransactionName()
    */
    @Nullable
    String getName();
    }

TransactionStatus 事务的一些状态信息,如是否一个新的事务、是否已被标记为回滚

public interface TransactionStatus extends SavepointManager, Flushable {

/**

  • 返回当前事务是否为新事务;否则将参与现有事务,或者可能不会首先在实际事务中运行。
    */
    boolean isNewTransaction();

/**

  • 返回此事务是否在内部携带保存点,即是否已基于保存点将其创建为嵌套事务。
  • 此方法主要是出于诊断目的,与{@link #isNewTransaction}一起使用。
  • 要以编程方式处理自定义保存点,请使用{@link SavepointManager}提供的操作
  • @see #isNewTransaction()
  • @see #createSavepoint()
  • @see #rollbackToSavepoint(Object)
  • @see #releaseSavepoint(Object)
    */
    boolean hasSavepoint();

/**

  • 仅设置事务回滚。这将指示事务管理器事务的唯一可能结果可能是回滚,作为引发异常的替代方法,
  • 后者将反过来触发回滚。这主要用于{@link org.springframework.transaction.support.TransactionTemplate}
  • 或{@link org.springframework.transaction.interceptor.TransactionInterceptor},
  • 其中实际的提交/回滚决策由容器做出。
  • @see org.springframework.transaction.support.TransactionCallback#doInTransaction
  • @see org.springframework.transaction.interceptor.TransactionAttribute#rollbackOn
    */
    void setRollbackOnly();

/**

  • 返回事务是否已被标记为仅回滚(通过应用程序或通过事务基础结构)
    */
    boolean isRollbackOnly();

/**

  • 如果适用,将基础会话刷新到数据存储区:例如,所有受影响的Hibernate / JPA会话。
  • 实际上,这只是一个提示,如果基础事务管理器没有flush概念,则可能是不做任何事情。
  • 刷新信号可以应用于主资源或事务同步,具体取决于底层资源。
    */
    @Override
    void flush();

/**

  • 返回此事务是否已完成,即是否已提交或回滚。
  • @see PlatformTransactionManager#commit
  • @see PlatformTransactionManager#rollback
    */
    boolean isCompleted();
    }

事务的4个特点

原子性( Atomicity)

事务的所有操作要么全部成功,要么全部回滚。

一致性( Consistency)

总是从一个一致性的状态转换到另一个一致性的状态。

隔离性( Isolation)

多个事务并发执行时,一个事务的执行不应影响其他事务的执行

持久性( Durability)

已被提交的事务对数据库的修改应该永久保存在数据库中。

如果在操作前(事务还没有提交)服务器宕机或者断电,那么重启数据库以后,数据状态应该为 张三:100,李四:100 如果在操作后(事务已经提交)服务器宕机或者断电,那么重启数据库以后,数据状态应该为 张三:0,李四:200

什么是脏读、幻读、不可重复读

脏读

Read Uncommitted(读取未提交内容)在该隔离级别,所有事务都可以看到其他未提交事务的执行结果。本隔离级别很少用于实际应用,因为它的性能也不比其他级别好多少。读取未提交的数据,也被称之为脏读(Dirty Read)。

在时间点5,事务A再次查询数据时,事务B并没有提交事务,但是,新的数据也被事务A查出来了。这就是脏读。

不可重复读(虚读)

Read Committed(读取提交内容)是大多数数据库系统的默认隔离级别(比如Sql Server , Oracle,但不是MySQL默认的,Mysql默认Repeatable read)。它满足了隔离的简单定义:一个事务只能看见已经提交事务所做的改变。这种隔离级别 也支持所谓的不可重复读(Nonrepeatable Read),因为同一事务的其他实例在该实例处理其间可能会有新的commit,所以同一select可能返回不同结果。

时间点6之前,事务A中 3 5时间点两次查询结果是一致的。事务B提交事务以后,事务A中7时间点再次查询,查询到了新增的这条数据。在事务A中,多次查询的结果不一致,这就是“不可重复读”。

幻读

指一个线程中的事务读取到了另外一个线程中提交的insert的数据。

隔离级别

请查看源码中TransactionDefinition 注释

编程式事务

最简单的方式手动注入声明事物

@Autowired
private TransactionTemplate transactionTemplate;

简单示例

transactionTemplate.execute(new TransactionCallbackWithoutResult() {
@Override
protected void doInTransactionWithoutResult(TransactionStatus transactionStatus) {
// 写sql

// transactionStatus.setRollbackOnly();
}
});

TransactionCallbackWithoutResult:无返回值使用 TransactionCallback:有返回值使用

声明式事务

概述

Spring 的声明式事务管理在底层是建立在 AOP 的基础之上的。其本质是对方法前后进行拦截,然后在目标方法开始之前创建或者加入一个事务,在执行完目标方法之后根据执行情况提交或者回滚事务。

声明式事务最大的优点就是不需要通过编程的方式管理事务,这样就不需要在业务逻辑代码中掺杂事务管理的代码,只需在配置文件中做相关的事务规则声明(或通过等价的基于标注的方式),便可以将事务规则应用到业务逻辑中。因为事务管理本身就是一个典型的横切逻辑,正是 AOP 的用武之地。Spring 开发团队也意识到了这一点,为声明式事务提供了简单而强大的支持。

在开发中使用声明式事务,不仅因为其简单,更主要是因为这样使得纯业务代码不被污染,极大方便后期的代码维护。

和编程式事务相比,声明式事务唯一不足地方是,后者的最细粒度只能作用到方法级别,无法做到像编程式事务那样可以作用到代码块级别。但是即便有这样的需求,也存在很多变通的方法,比如,可以将需要进行事务管理的代码块独立为方法等等。

声明式事务管理也有两种常用的方式:

  • 基于和命名空间的xml配置文件;
  • 基于@Transactional注解。
  • Stringboot 需要在启动类中增加 @EnableTransactionManagement 可以配置如:@EnableTransactionManagement(mode = AdviceMode.PROXY,proxyTargetClass=true,order = Ordered.LOWEST_PRECEDENCE )
  • proxyTargetClass:是否是基于类的代理
  • mode:事务管理功能底层实现是用JDK动态代理还是AspectJ。一般默认使用java就可以
  • order:aop拦截顺序,默认最低优先级,这样的好处是自己做的aop拦截都可以在此之上

@Transactional的属性

  • value 适用场景:在一个系统中,需要访问多个数据源或者多个数据库,则必然会配置多个事务管理器的
    自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数Java工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年Java开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Java开发知识点,真正体系化!

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!

如果你觉得这些内容对你有帮助,可以扫码获取!!(备注Java获取)

img

总结

面试建议是,一定要自信,敢于表达,面试的时候我们对知识的掌握有时候很难面面俱到,把自己的思路说出来,而不是直接告诉面试官自己不懂,这也是可以加分的。

以上就是蚂蚁技术四面和HR面试题目,以下最新总结的最全,范围包含最全MySQL、Spring、Redis、JVM等最全面试题和答案,仅用于参考

一份还热乎的蚂蚁金服面经(已拿Offer)面试流程4轮技术面+1轮HR

《互联网大厂面试真题解析、进阶开发核心学习笔记、全套讲解视频、实战项目源码讲义》点击传送门即可获取!

面试建议是,一定要自信,敢于表达,面试的时候我们对知识的掌握有时候很难面面俱到,把自己的思路说出来,而不是直接告诉面试官自己不懂,这也是可以加分的。

以上就是蚂蚁技术四面和HR面试题目,以下最新总结的最全,范围包含最全MySQL、Spring、Redis、JVM等最全面试题和答案,仅用于参考

[外链图片转存中…(img-vT9HyPpN-1713665616562)]

《互联网大厂面试真题解析、进阶开发核心学习笔记、全套讲解视频、实战项目源码讲义》点击传送门即可获取!

  • 26
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值