首页 > 其他分享 >etcd 事务操作

etcd 事务操作

时间:2023-12-28 16:59:00浏览次数:33  
标签:clientv3 src 事务 err dest etcd 操作

etcd是分布式的、可靠的、分布式存储K-V系统,用于存储分布式系统中的关键数据。

ETCD 事务

基于 CAS(Compare and Swap,即比较再交换) 方式

etcd中事务时一组原子性操作,可以确保多操作之间的原子性,并且可以保证一组操作在执行期间不会被其他操作中断

什么是事务?

事务通常就是指数据库事务。事务具有 ACID 特性,即原子性、一致性、隔离性和持久性。

  • 原子性(Atomicity):事务作为一个整体被执行,包含在其中的对数据库的操作要么全部被执行,要么都不执行。
  • 一致性(Consistency):事务应确保数据库的状态从一个一致状态转变为另一个一致状态。一致状态的含义是数据库中的数据应满足完整性约束。
  • 隔离性(Isolation):多个事务并发执行时,一个事务的执行不应影响其他事务的执行。
  • 持久性(Durability):一个事务一旦提交,他对数据库的修改应该永久保存在数据库中。
 

GET ETCD 的包

go get github.com/coreos/etcd/clientv3
go mod edit -replace github.com/coreos/[email protected]=go.etcd.io/[email protected]
go mod edit -replace google.golang.org/[email protected]=google.golang.org/[email protected]

事务操作

package main

//etcd 事务操作使用txn 方式

import (
    "context"
    "fmt"
    "log"
    "strconv"
    "time"
    "github.com/coreos/etcd/clientv3"
)
type user struct{
    Key string
    Account int
    ModRevision int64
}
//函数通过name 获取etcd key中的值 
func getEtcd(cli *clientv3.Client,name string )(u user, err error){
    account := user{Key:name}
    ctx , cancel := context.WithTimeout(context.Background(), 10* time.Second)
    resp , err := cli.Get(ctx , account.Key)
    cancel()
    if err !=nil{
        err = fmt.Errorf("etcd get err")
        
    }
    if len(resp.Kvs) == 1 {
        account.ModRevision = resp.Kvs[0].ModRevision
        account.Account,_ = strconv.Atoi(string(resp.Kvs[0].Value))
    }
    
    return account , err
}
//运算操作,修改user 结构体的值。
func accountOperation(src ,dest *user,sum int )(err error){
    if src.Account <= 0{
        err = fmt.Errorf("金额不足")
        return
    }
    src.Account -= sum
    dest.Account += sum
    return err
}
//事务操作,两个key同时执行如果其中一个key 操作失败事务执行失败,反之执行成功 func work(cli *clientv3.Client , src,dest user)(err error){ txnReps, err := cli.Txn(context.TODO()).If( clientv3.Compare(clientv3.ModRevision(src.Key), "=", src.ModRevision), clientv3.Compare(clientv3.ModRevision(dest.Key), "=", dest.ModRevision), ).Then( clientv3.OpPut(src.Key,strconv.Itoa(src.Account)), clientv3.OpPut(dest.Key,strconv.Itoa(dest.Account)), ).Else( ).Commit() if err != nil{ err = fmt.Errorf("事务操作失败") return err } if !txnReps.Succeeded { err = fmt.Errorf("事务操作失败 %v %v\n",src,dest) return err } return err } func main(){
  //连接etcd cli ,err := clientv3.New(clientv3.Config{ Endpoints: []string{"127.0.0.1:2379"}, DialTimeout: time.Second *5, }) if err != nil { // log.Fatal(err) fmt.Printf("etcd connection tailed err:%v\n",err) return } defer cli.Close()
// 获取userC 的数据放到user 的结构体中 src,err := getEtcd(cli,"userC") if err != nil { fmt.Printf("etcd get %v failed err%v",src,err) return }
  // 获取userD 的数据放到user的结构体中 dest,err :=getEtcd(cli,"userD") if err != nil { fmt.Printf("etcd get %v failed err%v",dest,err) return }
// 对user 的结构体运算,如果src的值小于等于0时抛出异常 err = accountOperation(&src,&dest,10) if err !=nil{ log.Fatalf("账号: %v金额不足 当前余额:%v\n",src.Key,src.Account) return } fmt.Println(src,dest)
// 事务操作 err = work(cli ,src,dest) if err !=nil{ log.Fatalf("事务操作失败请重试 源:%v 目标:%v",src,dest) return } fmt.Println("事务操作已成功") }

 

标签:clientv3,src,事务,err,dest,etcd,操作
From: https://www.cnblogs.com/zhenhui/p/17933049.html

相关文章

  • 嵌入式教学实验箱_数字信号处理实验箱_操作教程:5-16 灰度图像线性变换(LCD显示)
    一、实验目的学习灰度图像线性变换的原理,掌握图像的读取方法,并实现在LCD上显示线性变换前后的图像。二、实验原理图像线性变换一般成像系统只具有一定的亮度范围,亮度的最大值与最小值之比称为对比度。由于形成图像的系统亮度有限,常出现对比度不足的弊病,使人眼观看图像时视觉效果很......
  • Windows 上常用的Command命令行操作
    打开命令行窗口的方法注意:DOS命令不区分大小写.ProgramFiles,在dos命令中完全可以用"progra~1"代替,加上英文引号是因为名称的中间有空格(即多于一个词)。操作 结果c:\Users\DELL>cd\programfiles c:\ProgramFiles>C:\Users\DELL>cd\"progra~1" C:\PROGRA~1>c:\Users\DELL>cdc......
  • 【 python 】《 Anaconda安装与操作 》
    安装包下载1)官网下载地址:https://www.anaconda.com/download2)其他版本下载地址:repo.anaconda.com/archive/详细安装步骤1、双击运行安装程序,点击Next2、点击IAgree3、点击Next4、选择安装路径,确保空间足够即可,然后点击Next5、勾选两个框,设置环境变量以及设为默认......
  • 操作系统os operation System
        OS是计算机系统的核心和灵魂,是计算机系统必不可少的组成部分;它也是计算机教学的核心内容,是计算机相关专业的核心课程。OS是硬件的首次扩充,又是最核心的系统软件,OS课程具有承上启下的重要作用,既能对先行课程:程序设计、计算机组成原理和数据结构等进行总结和提高;......
  • 一机多用,实现Line多开的便捷操作
    一机多用是指在一台设备上实现多种功能和应用的使用,这种方式既节省了成本,又方便了用户。而在手机应用方面,Line是一款非常流行的即时通讯软件,在生活和工作中被广泛使用。但是,很多人可能会遇到一个问题:如何在一台设备上同时登录多个Line账号呢?下面就介绍一种实现Line多开便捷操作的......
  • java进行数据库操作的并发控制的2种方法
    本文分享自华为云社区《java进行数据库操作的并发控制》,作者:张俭。在现代应用编码中,从数据库里面find出来,进行一些业务逻辑操作,最后再save回去。即:Personperson=personRepo.findById(id);person.setAge(18);personRepo.save(person);但是这样的业务操作,如果一个线程修改......
  • Redis事务
    其实redis的事务是个假事务,没有实现原子性,若要php支持事务,必须一起执行,其中incr会报错$status=$redis->multi()->lPush($key1,'1123')->lPush($key2,'2123')->incr("age","age")->exec();try{$redis=newRedis();$redis->c......
  • 化工行业ERP软件有哪几种?化工行业ERP系统哪个操作简单
         有些化工企业内部日常生产经营涉及部分危险原材料,而这些物料对包装、仓储、在库时间等有特殊的要求,因此需要企业建立严格的仓储环境信息体系。还有些化工企业存在各个业务部门之间信息传递不畅、仓库数据不清、对账困难、批次物料追溯难、没有建立完整的设备台账......
  • 短小精悍(4) - Rust操作系统随机数getrandom库介绍
    今天带来的是另一个“短小精悍”的库:getrandom。它的作用是从操作系统提供的随机数源获得一段随机数。用法getrandom的用法很简单,唯一需要了解的就是它内部的同名函数:pubfngetrandom(dest:&mut[u8])->Result<(),Error>它将会向dest中填充来自操作系统的随机数。示例:......
  • lightdb/postgresql中plpgsql、函数与操作符、表达式及其内部实现
    PG_PROCPG_OPERATORpg_opclass用于定义索引上的相关操作符,一般来说是同一类数据类型。pg_opfamiliy定义了相互兼容的数据类型的操作符,关系见https://www.postgresql.org/docs/9.1/catalog-pg-opclass.html。pg8.3引入pg_opfamilies,原因:Create "operatorfamilies" toimprove......