spring事务传播和隔离_Spring交易管理。 隔离和传播

spring事务传播和隔离

介绍 (Introduction)

In my opinion transaction management is a really important topic for each backend developer. In general, people don’t pay attention to it while using Spring framework.

我认为,对于每个后端开发人员而言,事务管理都是一个非常重要的主题。 通常,人们在使用Spring框架时不会关注它。

But I think, it is important to know how to use transactions properly. Because sometimes can happen that there was an exception thrown inside your method, but transaction was not rolled back and it is not clear why? Or some other “strange” cases.

但是我认为,重要的是要知道如何正确使用交易。 因为有时可能会发生方法内部抛出异常的情况,但是事务没有回滚并且不清楚为什么? 或其他一些“奇怪”的情况。

@交易 (@Transactional)

In spring there is @Transactional annotation that can be used for wrapping a method in a transaction. We can use it with interfaces (lowest priority), classes or certain methods (highest priority).

在Spring,有@Transactional批注可用于在事务中包装方法。 我们可以将其与接口(最低优先级),类或某些方法(最高优先级)一起使用。

@Transactional is applied only for public methods and method must be invoked from outside of the bean.

@Transactional仅适用于公共方法,并且必须从Bean外部调用方法。

@Transactional annotation has multiple parameters. I would like to focus on two of them: Isolation and Propagation.

@Transactional批注具有多个参数。 我想重点介绍其中两个:隔离和传播。

Isolation is one of the main properties of transactions (Atomicity, Consistency, Isolation, Durability). It describes visibility of changes applied by concurrent transactions to each other.

隔离是事务的主要属性之一(原子性,一致性,隔离性,持久性)。 它描述了并发事务彼此之间应用的更改的可见性。

In Spring it is possible to set one of the 5 isolation level values: DEFAULT, READ_UNCOMMITTED, READ_COMMITED, REPETABLE_READ and SERIALIZABLE. For example,

在Spring中,可以设置5个隔离级别值之一:DEFAULT,READ_UNCOMMITTED,READ_COMMITED,REPETABLE_READ和SERIALIZABLE。 例如,

@Transactional (isolation=Isolation.READ_COMMITED)

Each of these isolation levels may have or haven’t different side effects: “dirty” read, non-repeatable read and phantom read. What each of them means?

这些隔离级别中的每一个都可能具有或没有不同的副作用:“脏”读取,不可重复读取和幻像读取。 他们每个人是什么意思?

“Dirty” read — one transaction can read changes of a concurrent transaction, that were not committed yet.

“脏”读 -一个事务可以读取并发事务中尚未提交的更改。

If you like more diagrams as I do:

如果您像我一样喜欢更多图表:

Transaction T1 begins first, then we start transaction T2. After that T1 changes row with id=10 in database and T2 reads it. Something wrong happens and T1 is rolled back. And recording in T2 is dirty now.

事务T1首先开始,然后我们开始事务T2。 之后,T1更改数据库中id = 10的行,然后T2读取该行。 发生错误,T1被回滚。 现在在T2中的记录很脏。

Non-repeatable read — one transaction reads the same row twice, but gets different values because between these reads the data was updated by the concurrent transaction.

不可重复读取 -一个事务读取同一行两次,但是获得不同的值,因为在这些读取之间,数据是由并发事务更新的。

Phantom read — one transaction runs the same query twice, but gets a different set of rows as result, because of the changes applied by another concurrent transaction.

幻像读取 -一个事务运行两次相同的查询,但是由于另一个并发事务所应用的更改而导致获得不同的行集。

Let’s go back to the isolation levels and check their possible side effects.

让我们回到隔离级别并检查其可能的副作用。

  1. DEFAULT value is used when we want to use default isolation level of our RDBMS. Default value for PostgreSQL, Oracle and SQL server is READ_COMMITTED, for MySQL — REPEATABLE_READ.

    当我们要使用RDBMS的默认隔离级别时,将使用DEFAULT值。 对于MySQL,PostgreSQL,Oracle和SQL Server的默认值为READ_COMMITTED-REPEATABLE_READ。

  2. with READ_UNCOMMITTED isolation level, we can have all three side effects

    使用READ_UNCOMMITTED隔离级别,我们可以具有所有三种副作用

  3. READ_COMMITTED isolation level has one change in comparison with READ_UNCOMMITTED — it prevents “dirty” reads.

    与READ_UNCOMMITTED相比,READ_COMMITTED隔离级别有一个更改-它防止“脏”读取。

  4. REPEATABLE_READ prevents “dirty” and non-repeatable reads.

    REPEATABLE_READ防止“脏”和不可重复的读取。

  5. SERIALIZABLE isolation level prevents all mentioned above side effects. It performs all transactions in sequence.

    SERIALIZABLE隔离级别可防止上述所有副作用。 它按顺序执行所有事务。

Isolation levelPhantom readNon-repeatable read“Dirty” read
READ_UNCOMMITTEDpossiblepossiblepossible
READ_COMMITTEDpossiblepossiblenot possible
REPEATABLE_READpossiblenot possiblenot possible
SERIALIZABLEnot possiblenot possiblenot possible
隔离度 幻影阅读 不可重复读 “脏”读
READ_UNCOMMITTED 可能 可能 可能
READ_COMMITTED 可能 可能 不可能
REPEATABLE_READ 可能 不可能 不可能
可序列化 不可能 不可能 不可能

There is also another important parameter of @Transactional: propagation. Propagation can be set to REQUIRED, REQUIRES_NEW, MANDATORY, SUPPORTS, NOT_SUPPORTED, NESTED or NEVER. Example:

@Transactional还有另一个重要参数:传播。 传播可以设置为REQUIRED,REQUIRES_NEW,MANDATORY,SUPPORTS,NOT_SUPPORTED,NESTED或NEVER。 例:

@Transactional (propagation=Propagation.REQUIRED)
  1. REQUIRED propagation level uses an existing transaction if there is one. Otherwise creates a new transaction.

    如果存在,则传播级别将使用现有事务。 否则,创建一个新交易。

  2. REQUIRES_NEW propagation level says to suspend outer transaction (if there is one) and create a new one.

    REQUIRES_NEW传播级别表示要暂停外部事务(如果有)并创建一个新事务。

  3. MANDATORY propagation uses an existing transaction if there is one. Otherwise, an exception will be thrown.

    强制传播使用现有交易(如果有)。 否则,将引发异常。

  4. SUPPORTS propagation level uses the current transaction if there is one. Otherwise, doesn’t create a new one.

    SUPPORTS传播级别使用当前事务(如果有)。 否则,请勿创建新的。

  5. NOT_SUPPORTED suspends current transaction if there is one.

    如果有一笔交易,则NOT_SUPPORTED暂停当前交易。

  6. NESTED creates nested transaction when there is an existing transaction already or works like REQUIRED if there is no transaction.

    如果已经存在现有事务,则NESTED会创建嵌套事务;如果没有事务,则NESTED类似于REQUIRED。

  7. NEVER throws an exception if there is an active transaction.

    如果存在活动事务,则永远不会引发异常。

PropagationCalling method (outer)Called method (inner)
REQUIREDNoT2
REQUIREDT1T1
REQUIRES_NEWNoT2
REQUIRES_NEWT1T2
MANDATORYNoException
MANDATORYT1T1
NOT_SUPPORTEDNoNo
NOT_SUPPORTEDT1No
SUPPORTSNoNo
SUPPORTST1T1
NEVERNoNo
NEVERT1Exception
NESTEDNoT2
NESTEDT1T2
传播 调用方式(外) 调用方法(内部)
需要 没有 T2
需要 T1 T1
REQUIRES_NEW 没有 T2
REQUIRES_NEW T1 T2
强制性 没有 例外
强制性 T1 T1
不支持 没有 没有
不支持 T1 没有
技术支持 没有 没有
技术支持 T1 T1
决不 没有 没有
决不 T1 例外
嵌套 没有 T2
嵌套 T1 T2

Also interesting is that Spring framework does automatic transaction rollback only for unchecked (Runtime) exceptions. To change it we can use rollbackFor parameter. For example, we can put

同样有趣的是,Spring框架仅针对未经检查的(运行时)异常执行自动事务回滚。 要更改它,我们可以使用rollbackFor参数。 例如,我们可以把

@Transactional (rollbackFor=Exception.class)

结论 (Conclusion)

In the article, I tried to describe how to use Isolation and Propagation parameters of @Transactional in Spring.

在本文中,我试图描述如何在Spring中使用@Transactional的IsolationPropagation参数。

I remember how several years ago I had some problems with the chain of transactional method and I hope that my article can help other developers to avoid them and have more clear understanding of the topic.

我记得几年前我在事务方法链上遇到了一些问题,希望我的文章可以帮助其他开发人员避免使用它们,并对主题有更清晰的理解。

翻译自: https://habr.com/en/post/513644/

spring事务传播和隔离

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值