分布式事务实践(一): 事务的介绍

分布式事务

分布式系统由于整个系统涉及到很多的服务,不同服务之间可能会对共享的数据进行并发的修改,导致数据的不一致性.

数据的不一致性就是分布式事务主要解决的问题.

分布式事务主要讨论的问题有:

  1. 多进程并发修改共享数据如何保证数据一致性
  2. 不同的请求之间数据如何进行隔离
  3. 一个请求可能由多个服务共同完成,如何保证这些服务所有的操作要么同时成功要么同时失败?
  4. 一个请求如果由三个服务共同完成,如果前两个服务成功了,最后一个服务失败了,如何保证数据的回滚?

有过开发经历的同学都知道,在单服务的场景下,大多数场景下只需要增加@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

名词解释:

脏读 : 就是一个事务读到了另外一个未提交的数据.

幻读 : 在你开启的事务中,读到了别的事务提交的新增插入的数据.

不可重复读:不可重复读是重复读取了另外一个事务已经提交了的数据,当你在一个事务中读两次,同时别的事务改变了数据并提交了事务,你两次读到的数据就不一致.

可重复读:在你的事务中,读到的数据以你第一次读到的为准,即使别的事务在你读到数据之后进行修改了并提交了,你也不会读到已经提交的数据.

总结:

之所以关注事务之间的隔离级别本质是因为在高并发情况下,多个线程或是进程会操作同一个数据库中的共享数据,此时有多个事务存在,此时数据库的隔离级别影响到了事务并发操作数据,

最安全的隔离级别是可序列化,在这个隔离级别下,所有的事务都是线性的,而不是并行的,就像是<使用Zookeeper实现分布式锁>中所介绍的悲观死锁一样.但是性能最差.在Mysql中我们可以使用for update为表或是表中的行加锁.

性能最好的事务隔离级别就是读未提交,但是这种事务隔离级别造成共享数据不安全性,也就是线程不安全的,在高并发下违背事务的一致性.

MySQL事务操作

  1. 查询当前会话事务和全局事务:select @@global.tx_isolation,@@tx_isolation
  2. 设置事务的隔离级别:set trasaction isolation level read uncommited

MySQL事务操作

  1. MySql的事务隔离等级:可重复读

两个事务同时开启,事务2查询到batman金额是100元,事务1batman发生转账100元给superman,此时事务1中batman的账户为0元,但是在事物2中仍然查询到batman账户是100元(不论事务1是否已经提交,事务2查到的只和它第一次查询到的金额相等).

1.png

MySql中的锁机制

  1. mysql中的锁根据级别划分为读锁和写锁

其中X锁也可以用于分布式锁的应用,但是高并发的X锁极大影响到了查询操作,非常影响性能和用户体验,所以不建议使用

1). 读锁(共享锁/S锁)

当某个事务对这些数据加了读锁后,其他的事务只能对这些数据加读锁,也就是只能读取这些数据.

2). 写锁(排他锁/X锁)

写锁的作用是某个事务对数据加了写锁之后,其他事务不能对这些数据加任何锁。

3). 加S锁: select * from 表名称[where] lock in share mode

3.png

4). 加X锁 : select * from 表名称[where] for update;insert update delete操作也会加x锁

5.png
  1. 根据范围划分

1). 行锁: 锁住某几行(大部分InnoDB引擎支持)

2). 表锁: 锁住整个表(MyISAM引擎支持)

JDBC中的事务操作

            public class Demo {
            
                public static void main(String[] args) {
                    Connection con = null;
                    PreparedStatement ps = null;        
                    try {
                    con = JdbcUtil.getConnection();
                    con.setAutoCommit(false); //取消自动提交事务
                        ps = con.prepareStatement("update tb_account set money = money-200 where name='batman'");
                        ps.executeUpdate();
                        System.out.println(5 / 0);  //异常
                         ps = con.prepareStatement("update tb_account set money = money + 200 where name='superman'");
                         ps.executeUpdate();
                         con.commit();  //手动提交事务
                         System.out.println("事务提交成功");
                    } catch (Exception e) {
                        try {
                            con.rollback(); //出现异常,进行事务回滚
                            System.out.println("转账失败");
                        } catch (SQLException e1) {
                            e1.printStackTrace();
                        }
                        e.printStackTrace();
                    }finally {
                        JdbcUtil.closeConnection(ps, con);
                    }
                }
            }
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 214,100评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,308评论 3 388
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 159,718评论 0 349
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,275评论 1 287
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,376评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,454评论 1 292
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,464评论 3 412
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,248评论 0 269
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,686评论 1 306
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,974评论 2 328
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,150评论 1 342
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,817评论 4 337
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,484评论 3 322
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,140评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,374评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,012评论 2 365
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,041评论 2 351

推荐阅读更多精彩内容