分布式事务实践: 事务的介绍
Posted 差无知
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了分布式事务实践: 事务的介绍相关的知识,希望对你有一定的参考价值。
分布式事务研究的问题
分布式系统由于整个系统涉及到很多的服务,不同服务之间可能会对共享的数据进行并发的修改,导致数据的不一致性.
数据的不一致性就是分布式事务主要解决的问题.
分布式事务主要讨论的问题有:
多进程并发修改共享数据如何保证数据一致性
不同的请求之间数据如何进行隔离
一个请求可能由多个服务共同完成,如何保证这些服务所有的操作要么同时成功要么同时失败?
一个请求如果由三个服务共同完成,如果前两个服务成功了,最后一个服务失败了,如何保证数据的回滚?
有过开发经历的同学都知道,在单服务的场景下,大多数场景下只需要增加@Transaction的注解就可以了,但是在分布式环境下,往往是多个进程对共享数据进行并发修改.
如何保证数据的一致性同时保证分布式系统的性能就是分布式事务讨论的问题.
什么是事务
事务是一种可靠,一致的方式,是访问和操作数据库中的数据单元.
数据库中的事务:把多条SQL语句看成是一个整体的任务,这个整体的任务要么是语句全部执行成功,要么就是全部执行失败.
事务的特性ACID
原子性(Atomicity):
事务就是一个不可以分割的工作单位,事务中的操作要么全部成功,要么全部失败.
比如:Batman转账给Superman的过程,一开始Batman有100元,Superman有100元,Batman转账100元给Superman分为两个动作,分别是Batman扣除100元和Superman增加100元,这两个动作要么共同发生,要么全部失败,体现的就是原子性.
一致性(Consistency):
事务必须使数据库从一个一致性状态变换为另外一个一致性状态.
比如:Batman和Superman各100元,转账之前加起来200元,转账之后两者账户加起来还是200元.
隔离性(Isolation):
事务的隔离性是指多个用户并发访问数据库的时候,数据库为每一个用户开启一个事务,不能被其他的事务干扰,多个并发事务之间要相互的隔离.
比如:Batman和Superman各100元,在Batman给Superman转账的过程中,Superman去查询自己的账户,此时产生两个事务,显示的金额体现了事务的隔离级别.
持久性(Dependence):
持久性就是指一旦一个事务被提交了之后,它对数据库的改变就是永久的,接下来即使是数据库发生了故障也不能够对这个事务有任何的影响.
比如:Batman转账100元给Superman,转账事务结束后,数据库即使发生了故障,也无法对该转账事务结果产生影响.
事务的隔离级别
名字 | 隔离级别 | 脏读 | 不可重复读 | 幻读 | 数据库默认 |
---|---|---|---|---|---|
可序列化 | Serializable | 否 | 否 | 否 | |
可重复读 | Repeatable Read | 否 | 否 | 是 | mysql |
读提交 | Read Committed | 否 | 是 | 是 | Oracle 和 SQL Server |
读未提交 | Read Uncommited | 是 | 是 | 是 |
名词解释:
脏读 : 就是一个事务读到了另外一个未提交的数据.
幻读 : 在你开启的事务中,读到了别的事务提交的新增插入的数据.
不可重复读:不可重复读是重复读取了另外一个事务已经提交了的数据,当你在一个事务中读两次,同时别的事务改变了数据并提交了事务,你两次读到的数据就不一致.
可重复读:在你的事务中,读到的数据以你第一次读到的为准,即使别的事务在你读到数据之后进行修改了并提交了,你也不会读到已经提交的数据.
总结:
之所以关注事务之间的隔离级别本质是因为在高并发情况下,多个线程或是进程会操作同一个数据库中的共享数据,此时有多个事务存在,此时数据库的隔离级别影响到了事务并发操作数据,
最安全的隔离级别是可序列化,在这个隔离级别下,所有的事务都是线性的,而不是并行的,就像是中所介绍的悲观死锁一样.但是性能最差.在Mysql中我们可以使用for update为表或是表中的行加锁.
性能最好的事务隔离级别就是读未提交,但是这种事务隔离级别造成共享数据不安全性,也就是线程不安全的,在高并发下违背事务的一致性.
MySQL事务操作
查询当前会话事务和全局事务:
select @@global.tx_isolation,@@tx_isolation
设置事务的隔离级别:
set trasaction isolation level read uncommited
MySQL事务操作
MySql的事务隔离等级:可重复读
两个事务同时开启,事务2查询到batman金额是100元,事务1batman发生转账100元给superman,此时事务1中batman的账户为0元,但是在事物2中仍然查询到batman账户是100元(不论事务1是否已经提交,事务2查到的只和它第一次查询到的金额相等).
MySql中的锁机制
mysql中的锁根据级别划分为读锁和写锁
其中X锁也可以用于分布式锁的应用,但是高并发的X锁极大影响到了查询操作,非常影响性能和用户体验,所以不建议使用
1). 读锁(共享锁/S锁)
当某个事务对这些数据加了读锁后,其他的事务只能对这些数据加读锁,也就是只能读取这些数据.
2). 写锁(排他锁/X锁)
写锁的作用是某个事务对数据加了写锁之后,其他事务不能对这些数据加任何锁。
3). 加S锁: select * from 表名称[where] lock in share mode
4). 加X锁 : select * from 表名称[where] for update
;insert update delete操作也会加x锁
根据范围划分
1). 行锁: 锁住某几行(大部分InnoDB引擎支持)
2). 表锁: 锁住整个表(MyISAM引擎支持)
JDBC中的事务操作
分布式事务涉及到多种技术,在面试中经常会被问到,但是它不仅仅是单纯的技术,要和工作中具体的业务相结合才能真正融会贯通.
以上是关于分布式事务实践: 事务的介绍的主要内容,如果未能解决你的问题,请参考以下文章
分布式技术专题「架构实践于案例分析」总结和盘点目前常用分布式事务特别及问题分析(Seata-终)