博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
spring事务传播和隔离_Spring交易管理。 隔离和传播
阅读量:2511 次
发布时间:2019-05-11

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

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 level Phantom read Non-repeatable read “Dirty” read
READ_UNCOMMITTED possible possible possible
READ_COMMITTED possible possible not possible
REPEATABLE_READ possible not possible not possible
SERIALIZABLE not possible not possible not 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.

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

Propagation Calling method (outer) Called method (inner)
REQUIRED No T2
REQUIRED T1 T1
REQUIRES_NEW No T2
REQUIRES_NEW T1 T2
MANDATORY No Exception
MANDATORY T1 T1
NOT_SUPPORTED No No
NOT_SUPPORTED T1 No
SUPPORTS No No
SUPPORTS T1 T1
NEVER No No
NEVER T1 Exception
NESTED No T2
NESTED T1 T2
传播 调用方式(外) 调用方法(内部)
需要 没有 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.

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

翻译自:

spring事务传播和隔离

转载地址:http://wzdwd.baihongyu.com/

你可能感兴趣的文章
[LeetCode][JavaScript]Candy
查看>>
Mybatis分页插件
查看>>
sk_buff Structure
查看>>
oracle的级联更新、删除
查看>>
多浏览器开发需要注意的问题之一
查看>>
Maven配置
查看>>
HttpServletRequest /HttpServletResponse
查看>>
SAM4E单片机之旅——24、使用DSP库求向量数量积
查看>>
从远程库克隆库
查看>>
codeforces Unusual Product
查看>>
hdu4348 - To the moon 可持久化线段树 区间修改 离线处理
查看>>
springMVC中一个class中的多个方法
查看>>
Linux系统安装出错后出现grub rescue的修复方法
查看>>
线段树模板整理
查看>>
[教程][6月4日更新]VMware 8.02虚拟机安装MAC lion 10.7.3教程 附送原版提取镜像InstallESD.iso!...
查看>>
[iOS问题归总]iPhone上传项目遇到的问题
查看>>
Python天天美味(总) --转
查看>>
Spring Framework tutorial
查看>>
【VS开发】win7下让程序默认以管理员身份运行
查看>>
【机器学习】Learning to Rank 简介
查看>>