事务java一致性理解_一篇文章看懂事务的一致性

本文通过实例解析事务的一致性,介绍了事务的本质和事务隔离级别,包括SERIALIZABLE、REPEATABLE_READ、READ_COMMITTED等,揭示了事务如何在性能和一致性间权衡。
摘要由CSDN通过智能技术生成

一、前言

事务一直以来是一个玄之又玄的东西,非常难以理解。难以理解倒不是因为事务本身有多难,而是事务这个概念被各种刻意包装,以至于让人晕头转向,摸不着头脑。例如各种抽象的概念,一致性、持久性、原子性、持久性、读未提交、读已提交、可重复读、序列化,Spring也抽象了事务的传播属性,数据库本身又有各种锁,于是我们就晕头了。今天我们就来扒一扒事务,看看事务华丽外衣下的本质。本篇博客结合沈询的分享,加上自己的一些总结。

二、事务要解的最终问题——“一致性”

一致性是一个名词,其实这里实际上应该当成一个动词来理解,多个参与者达成一致,达成了共识,相互之间不扯皮。这样说可能比较抽象,举个生活中的例子。

一天,老王和老王老婆,同时去银行取钱,老王查了银行卡账号有1w块钱,于是取了出来,假设老王老婆和老王同时查询,也看到有1w块钱,于是点击取款,最后发现没钱可取了,于是要扯皮了,这就不一致了。

用一句通俗的话来描述事务的一致性:所有事务的参与方,眼所见,便是心所得。上面的例子中,老王老婆看到了卡上有1w,却没法取,于是就要扯皮了。这就是严苛的一致性所定义的内容。

下面我们来具体分析一下上面的例子。

首先引出事务单位的概念,事务单元就是完成一个具体的业务的最小单元,上面的例子中包含两个事务单元。按照正常的时间线,要想不扯皮,应该看到如下执行顺序。

89c19b9439b3f79c2429ede91abfd06f.png

但是扯皮的事情发生了,两个事务单元并行了,于是出现如下的执行顺序。事务单元二左移,与事务单元一并行。

08c9e7e30ca7ccc0b753c9a2f1a52d44.png

上面的场景似曾相识,其实就是和线程安全所描述的内容一摸一样,《一篇文章看懂Java并发和线程安全》,要想不扯皮,必须让访问的共享资源互斥,用Java代码可以描述成如下的代码:

public class Consistency {

public static void main(String[] args) {

ReentrantLock lock = new ReentrantLock();

lock.lock();

try {

int balance = query();// 查询余额

if (balance > 0) {

drawingOutCash();// 取出现金

}

} catch (Exception e) {

} finally {

lock.unlock();

}

}

}

要想强一致,所有的事务单元串行着执行,这就是事务隔离级别中的SERLALIZABLE,于是就引出了事务的隔离级别。

三、事务的隔离级别

强一致,必须让所有事物单元串行执行,这便是隔离级别中的SERLALIZABLE(序列化),但是这样系统的性能是可想而知的,几乎不可用,于是需要放宽对锁的要求,所以出现了其他的隔离级别。事务的隔离级别是以性能为由对一致性的破坏,它的出现是为了破坏一致性,而不是维持一致性。

事务单元与事务单元的关系只有四种:读读、读写、写读、写写

SERLALIZABLE(序列化)

0e6482ae9791a68ae9bcab28a3039d6b.png

要想进一步提升性能,于是出现了读写锁,这里就出现了两种隔离级别:REPEATABLE_READ(可重复读)和READ_COMMITED(读已提交)

REPEATABLE_READ(可重复读):

读锁不能被升级为写锁,那么对共享资源的写,就进不来,这样“读读”是可并行的,这样会出现幻读,因为在这个级别,表是不会被看做是共享资源的,所以可以insert

471f1bd688b80151e5f2df94d3052a88.png

READ_COMMITED(读已提交):

读锁可以被升级为写锁,那么当对共享资源正在读时,可以被写请求升级为写锁,那么这样“读读”、“读写”可以并行,于是出现了幻读、不可重复读等等现象

21b49ce58e4fde5aa28843780f19c6e9.png

READ_UNCOMMITTED

只加写锁,读不用申请锁,这样“读读”、“读写”、“写读”都可以并行,但“写写”还不能并行,于是所有的写都是串行,于是就有了脏读、不可重复读、幻读等等。

7a66acabcb2b88bb0347e6c42f250b14.png

这就是事务隔离级别的真相,事务隔离级别越低,并行度越好,一致性越低。

四、一句话总结

事务的一致性和线程安全所面对的问题一模一样,要想维持一致性,需要保证两点:共享变量的可见性、临界区代码访问的顺序性。

快乐源于分享。

此博客乃作者原创, 转载请注明出处

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值