From 75cc19ee2a7677c33de50e49aa5d231f7f83a632 Mon Sep 17 00:00:00 2001 From: wangliang <1991wangliang@gmail.com> Date: Wed, 25 Dec 2019 11:01:12 +0800 Subject: [PATCH] lesson01 --- _docs/txlcn/index.md | 598 ++++++++++++++++++ img/WX20191220-102719.png | Bin 0 -> 438200 bytes .../950B4878-0B07-4233-A5AA-F6E28A036A6E.png | Bin 0 -> 57442 bytes 3 files changed, 598 insertions(+) create mode 100644 _docs/txlcn/index.md create mode 100644 img/WX20191220-102719.png create mode 100644 img/txlcn/950B4878-0B07-4233-A5AA-F6E28A036A6E.png diff --git a/_docs/txlcn/index.md b/_docs/txlcn/index.md new file mode 100644 index 000000000..5b47eca18 --- /dev/null +++ b/_docs/txlcn/index.md @@ -0,0 +1,598 @@ +--- +title: 分布式事务从0到1 +permalink: /docs/txlcn-lessson01/ +--- + + + +### 前言 +随着分布式技术的发展,分布式事务问题越来越显著。如何解决分布式事务问题变得非常紧迫。当目前业界较为成熟的分布式事务框架尚不存在,且又因为分布式事务相关的实现原理介绍不够完善,就让我们从今天开始结合原理与实践一起动手去解决分布式事务问题吧。 + +关于事务的理论介绍 + +ACID 隔离级别 spring事务传播行为 乐观锁悲观锁 BASE理论 ACP理论 + + +#### ACID理论 +在解决分布式事务这个问题之前,我们先来回顾一下什么事务,先理解事务的本质,先来看看本地事务的ACID理论。 + + +* 原子性(Atomicity) +原子性是指事务是一个不可分割的工作单位,事务中的操作要么都发生,要么都不发生。 + +* 一致性(Consistency) +一致性是指在事务开始之前和事务结束以后,数据库的完整性约束没有被破坏。这是说数据库事务不能破坏关系数据的完整性以及业务逻辑上的一致性。 + +* 隔离性(Isolation) +事务的隔离性是多个用户并发访问数据库时,数据库为每一个用户开启的事务,不能被其他事务的操作数据所干扰,多个并发事务之间要相互隔离 + +* 持久性Durability) +这是最好理解的一个特性:持久性,意味着在事务完成以后,该事务所对数据库所作的更改便持久的保存在数据库之中,并不会被回滚。(完成的事务是系统永久的部分,对系统的影响是永久性的,该修改即使出现致命的系统故障也将一直保持) + +#### 数据库的隔离级别 + +- √为会发生,×为不会发生: + +| 隔离级别 | 脏读 | 不可重复读 | 幻读 | +| :---- | :---- | :---- | :---- | +| read uncommitted(未提交读) | √ | √ | √ | +| read committed(提交读) | x |√ | √ | +| repeatable read(可重复读 | x | x | √ | +| serialization(可串行化) | x | x| x | + +再总结mysql 的常用命令(下面会用到): +查看MySQL隔离级别: `SELECT @@tx_isolation` +会话层面设置隔离级别: `set session transaction isolation level 隔离级别` +开启事务: `start transaction` +提交事务:`commit` +回滚事务:`rollback` + + +##### 脏读演示 +表中的数据如下,设置隔离级别为未提交读 + +| id | name | balacne | +| ---- | ---- | ---- | +| 1 | 张三 | 1000 | +| 2 | 李四 | 0 | + +执行流程 + +
时间 | +客户端A | +客户端B | +
---|---|---|
T1 | ++set session transaction isolation level read uncommitted;start transaction(开启事务); +update account set balance = balance+1000 where id = 1; +select * from account where id = 1; +设置为未提交读,给张三账号+1000,输出为2000 + | ++ + | +
T2 | ++ + | ++set session transaction isolation level read uncommitted; +start transaction; +select * from account where id = 1; +查询余额输出为2000 + | +
T3 | ++rollback + | ++ + | +
T4 | ++ + | ++commit + | +
T5 | ++ + | ++select * from account where id = 1; +查询余额输出为1000 + | +
时间 | +客户端A | +客户端B | +
---|---|---|
T1 | ++set session transaction isolation level read uncommitted; +start transaction; +update account set balance = balance-1000 where id = 1; +update account set balance = balance+1000 where id = 2; + | ++ + | +
T2 | ++ + | ++set session transaction isolation level read uncommitted; +start transaction; +select balance from account where id = 2; +update account set balance = balance -1000 where id = 2; +更新语句被阻塞 + | +
T3 | ++rollback + | ++ + | +
T4 | ++ + | ++commit + | +
时间 | +客户端A | +客户端B | +
---|---|---|
T1 | ++set session transaction isolation level read committed; +start transaction; +select * from account where id = 2; +查询出余额输出为0; + | ++ + | +
T2 | ++ + | ++set session transaction isolation level read committed; +start transaction; +update account set balance = balance + 1000 where id = 2; +select * from account where id = 2; +commit; +查询余额输出1000 + | +
T3 | ++select * from account where id = 2; +commit; +查询余额输出1000 + | ++ + | +
时间 | +客户端A | +客户端B | +
---|---|---|
T1 | ++set session transaction isolation level repeatable read; +start transaction; +select * from account where id = 2; +查询出余额输出为0; + | ++ + | +
T2 | ++ + | ++set session transaction isolation level repeatable read; +start transaction; +update account set balance = balance + 1000 where id = 2; +select * from account where id = 2; +commit; +查询余额输出1000 + | +
T3 | ++select * from account where id = 2; +commit; +查询余额输出0 + | ++ + | +
时间 | +客户端A | +客户端B | +
---|---|---|
T1 | ++set session transaction isolation level repeatable read; +start transaction; +select count(*) from account where id <=10; +输出2; + | ++ + | +
T2 | ++ + | ++set session transaction isolation level repeatable read; +start transaction; +insert into account(id,name,balance) values(“3”,“王五”,“0”) ; +select count(*) from account where id <=10; +commit; +输出3 + | +
T3 | ++select count(*) from account where id <=10; +commit; +输出2 + | ++ + | +
时间 | +客户端A | +客户端B | +
---|---|---|
T1 | ++set session transaction isolation level repeatable read; +start transaction; +select count(*) from account where id =3; +输出0; + | ++ + | +
T2 | ++ + | ++set session transaction isolation level repeatable read; +start transaction; +insert into account(id,name,balance) values(“3”,“王五”,“0”) ; +commit; + | +
T3 | ++insert into account(id,name,balance) values(“3”,“王五”,“0”); +主键重复,插入失败 + | ++ + | +
T4 | ++select count(*) from account where id =3; +输出0; + | ++ + | +
T5 | ++rollback; + | ++ + | +
=#%mXDi()yXIBsN6
zDf;T;nm-NDlKCf|N>hq0A%sddNS9qhzba}O^m5NJwHH9M&u$hXT}4|3rp%oVg8FmK
z1`{#Hl`$X2R3$ea0n*AmW)s;M6OO^FJQ^?0Wvq;Om=6_*0<>J2rC*UzZxPF+t^j>0
zL319@5q24yhjssQTwXeaV2?7{Mqb^6>I+g1u(sX8a_nAI&PByQ@VwKzchiXSnO}`l
zXT|!`zIlj$UjL!dS%3IuJ5_TiLC&%*)6!{d&Avaby!W)#h897(RCqW4PSYaP;#1-4
zDNRQ?c{F?qH4U`$*XuZKvI8{2m5;#n=9uT8YnfJjd&teLKno6>S&cDmOFydIfEN68
zl+~14p7bPB==na&8Lf`7`8H?L`o*W5MeT}E {s$PP)D$FIZ%euLs
z1!YG84|-gt_38YQNrdIH*w@2Z#y)D(I8|5)$)EY8qcun18cAo6t>@Dj(83J!D&Nk%
zvvB8z%*x(*b1wWdMp{m}{7H4sROYmy; WI0UB5eh3LTCyW7+YzQeko^sOqwp7SC>)OPg~GH&nxx2?A=!Il
zUkfPIUgh8Ke=^_qtwLexo*t4;;H~F*ayfbO ^Nsfe*Hhk7_1YJpJ4#6v6>fQ2M
z#z|a#kH7ihGGoHiv|SM$8CQ+o
z4)B8al8A|iu%`G4Lq_?@KmkJFhc;zn)yka1GI%D8zp+6pkWLH%1($j7X|Cbaw|5nq
zB{$A86_PR5dOoAHXY5!4CtXE`h7n7Z%Tmm%ek#-CGrzNru=+oj4`VuT1dDC41+FVc
zgG?D$!jQh>81c_NWE6R6VI8*L=b-wR!
h)nG(YN34bG<+r3bvU@aV%2vt*Z`ri`2>XJdxX>X9&&rZc8)r1e1j^b2OBNA9Ry@L!Y{
zP=Q0O6~n>~3L`3TSa%jg+AXL``q*h?p9$m~=#EN<