Spring的7 种事务传播行为Word文档下载推荐.docx

上传人:b****3 文档编号:15716942 上传时间:2022-11-15 格式:DOCX 页数:7 大小:84.77KB
下载 相关 举报
Spring的7 种事务传播行为Word文档下载推荐.docx_第1页
第1页 / 共7页
Spring的7 种事务传播行为Word文档下载推荐.docx_第2页
第2页 / 共7页
Spring的7 种事务传播行为Word文档下载推荐.docx_第3页
第3页 / 共7页
Spring的7 种事务传播行为Word文档下载推荐.docx_第4页
第4页 / 共7页
Spring的7 种事务传播行为Word文档下载推荐.docx_第5页
第5页 / 共7页
点击查看更多>>
下载资源
资源描述

Spring的7 种事务传播行为Word文档下载推荐.docx

《Spring的7 种事务传播行为Word文档下载推荐.docx》由会员分享,可在线阅读,更多相关《Spring的7 种事务传播行为Word文档下载推荐.docx(7页珍藏版)》请在冰豆网上搜索。

Spring的7 种事务传播行为Word文档下载推荐.docx

隔离性(Isolation)。

要想真正的做到操作之间完全没有任何干扰是很难的,于是乎,每天上班打酱油的数据库专家们,开始动脑筋了,“我们要制定一个规范,让各个数据库厂商都支持我们的规范!

”,这个规范就是:

事务隔离级别(TransactionIsolationLevel)。

能定义出这样牛逼的规范真的挺不容易的,其实说白了就四个级别:

1.READ_UNCOMMITTED

2.READ_COMMITTED

3.REPEATABLE_READ

4.SERIALIZABLE

千万不要去翻译,那只是一个代号而已。

从上往下,级别越来越高,并发性越来越差,安全性越来越高,反之则反。

当我们执行一条insert语句后,数据库必须要保证有一条数据永久地存放在磁盘中,这个也算事务的一条特性, 

它就是:

持久性(Durability)。

归纳一下,以上一共提到了事务的4条特性,把它们的英文单词首字母合起来就是:

ACID,这个就是传说中的“事务ACID特性”!

真的是非常牛逼的特性啊!

这4条特性,是事务管理的基石,一定要透彻理解。

此外还要明确,这四个家伙当中,谁才是老大?

其实想想也就清楚了:

原子性是基础,隔离性是手段,持久性是目的,真正的老大就是一致性。

数据不一致了,就相当于“江湖乱套了,流氓戴胸罩”。

所以说,这三个小弟都是跟着“一致性”这个老大混,为他全心全意服务。

这四个家伙当中,其实最难理解的反倒不是一致性,而是隔离性。

因为它是保证一致性的重要手段,是工具,使用它不能有半点差池,否则后果自负!

怪不得数据库行业专家们都要来研究所谓的事务隔离级别了。

其实,定义这四个级别就是为了解决数据在高并发下所产生的问题,那又有哪些问题呢?

1.DirtyRead(脏读)

2.UnrepeatableRead(不可重复读)

3.PhantomRead(幻读)

首先看看“脏读”,看到“脏”这个字,我就想到了恶心、肮脏。

数据怎么可能脏呢?

其实也就是我们经常说的“垃圾数据”了。

比如说,有两个事务,它们在并发执行(也就是竞争)。

看看以下这个表格,您一定会明白我在说什么:

时间

事务A(存款)

事务B(取款)

T1

开始事务

T2

T3

查询余额(1000元)

T4

取出1000元(余额0元)

T5

查询余额(0元)

T6

撤销事务(余额恢复为1000元)

T7

存入500元(余额500元)

T8

提交事务

余额应该为1500元才对!

请看T5时间点,事务A此时查询余额为0元,这个数据就是脏数据,它是事务B造成的,明显事务没有进行隔离,渗过来了,乱套了。

所以脏读这件事情是非常要不得的,一定要解决掉!

让事务之间隔离起来才是硬道理。

那第2条,不可重复读又怎么解释呢?

还是用类似的例子来说明:

事务A其实除了查询了两次以外,其他什么事情都没有做,结果钱就从1000变成0了,这就是重复读了。

可想而知,这是别人干的,不是我干的。

其实这样也是合理的,毕竟事务B提交了事务,数据库将结果进行了持久化,所以事务A再次读取自然就发生了变化。

这种现象基本上是可以理解的,但在有些变态的场景下却是不允许的。

毕竟这种现象也是事务之间没有隔离所造成的,但我们对于这种问题,似乎可以忽略。

最后一条,幻读。

我去!

Phantom这个单词不就是“幽灵、鬼魂”吗?

刚看到这个单词时,真的把我的小弟弟都给惊呆了。

怪不得这里要翻译成“幻读”了,总不能翻译成“幽灵读”、“鬼魂读”吧。

其实意义就是鬼在读,不是人在读,或者说搞不清楚为什么,它就变了,很晕,真的很晕。

还是用一个示例来说话吧:

事务A(统计总存款)

事务B(存款)

统计总存款(10000元)

存入100元

统计总存款(10100元)

银行工作人员,每次统计总存款,都看到不一样的结果。

不过这也确实也挺正常的,总存款增多了,肯定是这个时候有人在存钱。

但是如果银行系统真的这样设计,那算是玩完了。

这同样也是事务没有隔离所造成的,但对于大多数应用系统而言,这似乎也是正常的,可以理解,也是允许的。

银行里那些恶心的那些系统,要求非常严密,统计的时候,甚至会将所有的其他操作给隔离开,这种隔离级别就算非常高了(估计要到SERIALIZABLE级别了)。

归纳一下,以上提到了事务并发所引起的跟读取数据有关的问题,各用一句话来描述一下:

1.脏读:

事务A读取了事务B未提交的数据,并在这个基础上又做了其他操作。

2.不可重复读:

事务A读取了事务B 

已提交的更改数据。

3.幻读:

事务A读取了事务B已提交的新增数据。

第一条是坚决抵制的,后两条在大多数情况下可不作考虑。

这就是为什么必须要有事务隔离级别这个东西了,它就像一面墙一样,隔离不同的事务。

看下面这个表格,您就清楚了不同的事务隔离级别能处理怎样的事务并发问题:

事务隔离级别

脏读

不可重复读

幻读

READ_UNCOMMITTED

允许

READ_COMMITTED

禁止

REPEATABLE_READ

SERIALIZABLE

根据您的实际需求,再参考这张表,最后确定事务隔离级别,应该不再是一件难事了。

JDBC也提供了这四类事务隔离级别,但默认事务隔离级别对不同数据库产品而言,却是不一样的。

我们熟知的MySQL数据库的默认事务隔离级别就是 

READ_COMMITTED,Oracle、SQLServer、DB2等都有有自己的默认值。

我认为READ_COMMITTED已经可以解决绝大多数问题了,其他的就具体情况具体分析吧。

若对其他数据库的默认事务隔离级别不太清楚,可以使用以下代码来获取:

DatabaseMetaDatameta=DBUtil.getDataSource().getConnection().getMetaData();

intdefaultIsolation=meta.getDefaultTransactionIsolation();

提示:

在java.sql.Connection类中可查看所有的隔离级别。

我们知道JDBC只是连接Java程序与数据库的桥梁而已,那么数据库又是怎样隔离事务的呢?

其实它就是“锁”这个东西。

当插入数据时,就锁定表,这叫“锁表”;

当更新数据时,就锁定行,这叫“锁行”。

当然这个已经超出了我们今天讨论的范围,所以还是留点空间给我们的DBA同学吧,免得他没啥好写的了。

除了JDBC给我们提供的事务隔离级别这种解决方案以外,还有哪些解决方案可以完善事务管理功能呢?

不妨看看Spring的解决方案吧,其实它是对JDBC的一个补充或扩展。

它提供了一个非常重要的功能,就是:

事务传播行为(TransactionPropagationBehavior)。

确实够牛逼的,Spring一下子就提供了7种事务传播行为,这7种行为一出现,真的是亮瞎了我的狗眼!

1.PROPAGATION_REQUIRED

2.RROPAGATION_REQUIRES_NEW

3.PROPAGATION_NESTED

4.PROPAGATION_SUPPORTS

5.PROPAGATION_NOT_SUPPORTED

6.PROPAGATION_NEVER

7.PROPAGATION_MANDATORY

看了 

Spring参考手册之后,更是晕了,这到底是在干嘛?

首先要明确的是,事务是从哪里来?

传播到哪里去?

答案是,从方法A传播到方法B。

Spring解决的只是方法之间的事务传播,那情况就多了,比如:

1.方法A有事务,方法B也有事务。

2.方法A有事务,方法B没有事务。

3.方法A没有事务,方法B有事务。

4.方法A没有事务,方法B也没有事务。

这样就是4种了,还有3种特殊情况。

还是用我的Style给大家做一个分析吧:

假设事务从方法A传播到方法B,您需要面对方法B,问自己一个问题:

方法A有事务吗?

1.如果没有,就新建一个事务;

如果有,就加入当前事务。

这就是 

PROPAGATION_REQUIRED,它也是Spring提供的默认事务传播行为,适合绝大多数情况。

2.如果没有,就新建一个事务;

如果有,就将当前事务挂起。

RROPAGATION_REQUIRES_NEW,意思就是创建了一个新事务,它和原来的事务没有任何关系了。

3.如果没有,就新建一个事务;

如果有,就在当前事务中嵌套其他事务。

PROPAGATION_NESTED,也就是传说中的“嵌套事务”了,所嵌套的子事务与主事务之间是有关联的(当主事务提交或回滚,子事务也会提交或回滚)。

4.如果没有,就以非事务方式执行;

如果有,就使用当前事务。

PROPAGATION_SUPPORTS,这种方式非常随意,没有就没有,有就有,有点无所谓的态度,反正我是支持你的。

5.如果没有,就以非事务方式执行;

PROPAGATION_NOT_SUPPORTED,这种方式非常强硬,没有就没有,有我也不支持你,把你挂起来,不鸟你。

6.如果没有,就以非事务方式执行;

如果有,就抛出异常。

PROPAGATION_NEVER,这种方式更猛,没有就没有,有了反而报错,确实够牛的,它说:

我从不支持事务!

7.如果没有,就抛出异常;

PROPAGATION_MANDATORY,这种方式可以说是牛逼中的牛逼了,没有事务直接就报错,确实够狠的,它说:

我必须要有事务!

看到我上面这段解释,小伙伴们是否已经感受到,被打通任督二脉的感觉?

多读几遍,体会一下,就是您自己的东西了。

需要注意的是 

PROPA

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 经管营销 > 经济市场

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1