文档章节

分布式数据一致性

狼王黄师傅
 狼王黄师傅
发布于 05/19 15:23
字数 1008
阅读 10
收藏 0

 

 

 

 

代码示例:

package com.imooc.example.localtranjdbc;


import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.SQLException;

public class LocalTranJdbcApplication {

    private static final Logger LOG = LoggerFactory.getLogger(LocalTranJdbcApplication.class);

    public static void main(String[] args) throws SQLException {


        String plusAmountSQL = "UPDATE T_USER SET amount = amount + 100 WHERE username = ?";
        String minusAmountSQL = "UPDATE T_USER SET amount = amount - 100 WHERE username = ?";

        Connection dbConnection = getDBConnection();
        LOG.debug("Begin");
        dbConnection.setAutoCommit(false);

        PreparedStatement plusAmountPS = dbConnection.prepareStatement(plusAmountSQL);
        plusAmountPS.setString(1, "SuperMan");
        plusAmountPS.executeUpdate();

        simulateError();

        PreparedStatement minusAmountPS = dbConnection.prepareStatement(minusAmountSQL);
        minusAmountPS.setString(1, "BatMan");
        minusAmountPS.executeUpdate();

        dbConnection.commit();
        LOG.debug("Done!");

        plusAmountPS.close();
        minusAmountPS.close();
        dbConnection.close();
    }

    private static void simulateError() throws SQLException {
        throw new SQLException("Simulate some error!");
    }

    private static Connection getDBConnection() throws SQLException {
        String DB_DRIVER = "com.mysql.jdbc.Driver";
        String DB_CONNECTION = "jdbc:mysql://localhost:3306/dist_tran_course";
        String DB_USER = "mt";
        String DB_PASSWORD = "111111";
        try {
            Class.forName(DB_DRIVER);
        } catch (ClassNotFoundException e) {
            LOG.error(e.getMessage());
        }
        return DriverManager.getConnection(DB_CONNECTION, DB_USER, DB_PASSWORD);
    }
}

    (1)若将上述代码在commit()处,启动断点执行。同时启动一个另一段代码。

    另一段代码不采取事务的方式,先执行在SuperMan 的余额加100的更新操作。

    "UPDATE T_USER SET amount = amount  + 100 WHERE username = 'SuperMan'"

    此时,另一段代码将卡在更新操作处,原因是:第一段代码更新操作锁住了该条记录。

    让第一段代码执行完毕之后,第二段代码也执行成功。此时SuperMan的余额为300,BatMan余额为0.

    即先执行第一段成功,后执行成功余额加100的操作.结果没问题

 

    (2)若将上述代码在commit()处,启动断点执行。同时启动一个另一段代码。

    另一段代码不采取事务的方式,先执行在查询出SuperMan 的余额,然后执行在查询出的余额上加100的更新操作。

    "SELECT * FROM T_USER WHERE username = 'SuperMan'"

    "UPDATE T_USER SET amount =" + (amount  + 100) + " WHERE username = 'SuperMan'"

    此时,另一段代码将卡在更新操作处,原因是:第一段代码更新操作锁住了该条记录。

    让第一段代码执行完毕之后,第二段代码也执行成功。此时SuperMan的余额为200,BatMan余额为0.

    即先第二段代码查询出SuperMan的余额为100,然后执行第一段成功,后执行更新当前余额为200的操作。结果有问题(读取了脏数据)

 

(3)若将上述代码在commit()处,启动断点执行。同时启动一个另一段代码。

    另一段代码不采取事务的方式,先执行在查询出SuperMan 的余额,然后执行在查询出的余额上加100的更新操作。

    "SELECT * FROM T_USER WHERE username = 'SuperMan' FOR UPDATE"

    "UPDATE T_USER SET amount =" + (amount  + 100) + " WHERE username = 'SuperMan'"

    此时,另一段代码将卡在查询操作处,原因是:第一段代码更新操作锁住了表,而 FOR UPDATE 会等待行锁释放之后,返回查询结果。

    让第一段代码执行完毕之后,第二段代码也执行成功。此时SuperMan的余额为300,BatMan余额为0.

    即先执行第一段成功,然后第二段代码查询出SuperMan的余额为200,后执行更新当前余额为300的操作.结果没问题

    PS:FOR UPDATE 会将查询出的记录加锁,不允许其他用户对其进行修改和删除操作。

        若当前select发现自己的结果集中有一条或者多条数据正在被修改(如:有其他的语句进行了 for update),那么该语句就会一直等待该记录修改完毕并释放锁,然后继续再执行。

 InnoDB引擎中,默认是行级别的锁,当有明确指定的主键时候,是行级锁。否则是表级别。

假设表foods ,存在有id、name、status三个字段,id是主键,status有索引。

例1: (明确指定主键,并且有此记录,行级锁) 
SELECT * FROM foods WHERE id=1 FOR UPDATE; 
SELECT * FROM foods WHERE id=1 and name=’咖啡色的羊驼’ FOR UPDATE;

例2: (明确指定主键/索引,若查无此记录,无锁) 
SELECT * FROM foods WHERE id=-1 FOR UPDATE;

例3: (无主键/索引,表级锁) 
SELECT * FROM foods WHERE name=’咖啡色的羊驼’ FOR UPDATE;

例4: (主键/索引不明确,表级锁) 
SELECT * FROM foods WHERE id<>’3’ FOR UPDATE; 
SELECT * FROM foods WHERE id LIKE ‘3’ FOR UPDATE;

 

 

 

© 著作权归作者所有

上一篇: JVM目录
下一篇: 中台的概念
狼王黄师傅
粉丝 16
博文 258
码字总数 542365
作品 0
成都
程序员
私信 提问
学习分布式不得不会的ACP理论

原创: Hollis 2000年7月,加州大学伯克利分校的Eric Brewer教授在ACM PODC会议上提出CAP猜想。2年后,麻省理工学院的Seth Gilbert和Nancy Lynch从理论上证明了CAP。之后,CAP理论正式成为分...

Java填坑之路
2018/07/17
0
0
[mongodb文档]分布式一致性

[mongodb文档]分布式一致性(一)[1] 一致性模型对于一个分布式数据库来说是至关重要的。这里我们将专门一个专题的形式来讲解一些主题:例如:针对一些具体的应用场景应该使用什么样的模型。...

nileader
2014/06/05
0
0
二:分布式系统事务

一:事务 --->是由一系列对系统中数据进行访问与更新的操作所组成的一个程序执行逻辑单元。保证数据在业务逻辑上是正确的。 --->事务的四大特征:原子性,一致性,隔离性,持久性。简称事务的...

无信不立
2016/02/17
0
0
CAP原理和最终一致性(Eventually Consistency)

在足球比赛里,一个球员在一场比赛中进三个球,称之为帽子戏法(Hat-trick)。在分布式数据系统中,也有一个帽子原理(CAP Theorem),不过此帽子非彼帽子。CAP原理中,有三个要素: 一致性(Cons...

liangtee
2014/07/30
0
0
"一言蔽之系列"--简说SQL与NoSQL那些事

一言蔽之,NoSQL ==Not Only SQL ,字面意思是“不仅仅是SQL”,是一类非关系型存储的数据库的统称 文章结构: 1、关系型数据库:ACID理论 2、非关型系数据库:分布式存储理论、CAP理论、BAS...

流川枫AI
2017/04/19
0
0

没有更多内容

加载失败,请刷新页面

加载更多

win mysql 安装笔记

官方下载zip的mysql包,解压即可 目录: D:\mysql_file\mysql-5.7.26-winx64 在该目录下新建一个文件夹data (如果操作过程中失败,要把data中的所有文件删掉) 新建一个文件,命名为my.ini,内容...

_大侠__
15分钟前
1
0
第八届“中国软件杯”初赛评审完美收官,课工场赛题备受关注

日前,由工业和信息部、教育部、江苏省人民政府共同创办第八届“中国软件杯”大学生软件设计大赛初赛评审历时两天,于 6 月 23 日圆满结束。由中国科学院软件研究所专家、各高校软件学院相关...

IFTNews
27分钟前
0
0
日期居然用字符串保存?我笑了

微信公众号「后端进阶」,专注后端技术分享:Java、Golang、WEB框架、分布式中间件、服务治理等等。 老司机倾囊相授,带你一路进阶,来不及解释了快上车! 我发现数据库有些日期居然用字符串...

后端进阶
30分钟前
2
0
c 基础教程四:c 输入输出(二)

在C语言中,有三个函数可以用来在显示器上输出数据,它们分别是: puts():只能输出字符串,并且输出结束后会自动换行 putchar():只能输出单个字符 printf():可以输出各种类型的数据 prin...

故城以南丶思念不安
31分钟前
1
0
SSO简单实现与理解

SSO英文全称Single Sign On,单点登录。SSO是在多个应用系统中,用户只需要登录一次就可以访问所有相互信任的应用系统。它包括可以将这次主要的登录映射到其他应用中用于同一个用户的登录的机...

如同相见恨晚
32分钟前
1
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部