golang使用CockroachDB

3 篇文章 0 订阅
2 篇文章 1 订阅

golang使用CockroachDB

步骤1.安装Go pq驱动程序

go get -u github.com/lib/pq

步骤2.创建maxroach用户和bank数据库

启动内置的SQL客户端:
cockroach sql --certs-dir=certs

在SQL Shell中,发出以下语句来创建maxroach用户和bank数据库:

CREATE USER IF NOT EXISTS maxroach;

CREATE DATABASE bank;

授予maxroach用户必要的权限:

GRANT ALL ON DATABASE bank TO maxroach;

退出SQL Shell:

\q

步骤3.为maxroach用户生成证书

maxroach通过运行以下命令为用户创建证书和密钥。代码示例将以该用户身份运行。

cockroach cert create-client maxroach --certs-dir=certs --ca-key=my-safe-directory/ca.key

步骤4.运行Go代码

现在已经有了一个数据库和一个用户,将运行代码来创建表并插入一些行,然后运行代码以作为原子事务读取和更新值。

基本陈述

首先,使用以下代码以maxroach用户身份连接并执行一些基本的SQL语句,创建表,插入行以及读取和打印行。

package main

import (
 "database/sql"
"fmt"
"log"

_ "github.com/lib/pq"
)

func main() {
	db, err := sql.Open("postgres",
    "postgresql://maxroach@localhost:26257/bank?ssl=true&sslmode=require&sslrootcert=certs/ca.crt&sslkey=certs/client.maxroach.key&sslcert=certs/client.maxroach.crt")
 	if err != nil {
    	log.Fatal("error connecting to the database: ", err)
	}
	defer db.Close()

	 if _, err := db.Exec(
    		"CREATE TABLE IF NOT EXISTS accounts (id INT PRIMARY KEY, balance INT)"); err != nil {
    		log.Fatal(err)
	}


	if _, err := db.Exec(
   			 "INSERT INTO accounts (id, balance) VALUES (1, 1000), (2, 250)"); err != nil {
   			 log.Fatal(err)
	 }


rows, err := db.Query("SELECT id, balance FROM accounts")
if err != nil {
    log.Fatal(err)
}
defer rows.Close()
fmt.Println("Initial balances:")
for rows.Next() {
    var id, balance int
    if err := rows.Scan(&id, &balance); err != nil {
        log.Fatal(err)
    }
    fmt.Printf("%d %d\n", id, balance)
}

}

创建事务(带重试逻辑)

Go代码:

package main

import (
	"context"
	"database/sql"
	"fmt"
	"log"

 "github.com/cockroachdb/cockroach-go/crdb"
)

func transferFunds(tx *sql.Tx, from int, to int, amount int) error {
 var fromBalance int
	if err := tx.QueryRow(
    	"SELECT balance FROM accounts WHERE id = $1", from).Scan(&fromBalance); err != nil {
    	return err
 }

	if fromBalance < amount {
   	 	return fmt.Errorf("insufficient funds")
	}

	if _, err := tx.Exec(
    	"UPDATE accounts SET balance = balance - $1 WHERE id = $2", amount, from); err != nil {
   	 return err
 }
	if _, err := tx.Exec(
   	 "UPDATE accounts SET balance = balance + $1 WHERE id = $2", amount, to); err != nil {
   	 return err
	}
	return nil
}

func main() {
	//非安全模式
	db, err := sql.Open("postgres", "postgresql://maxroach@localhost:26257/bank?sslmode=disable")
	//安全模式
 	//db, err := sql.Open("postgres", "postgresql://maxroach@localhost:26257/bank?ssl=true&sslmode=require&sslrootcert=certs/ca.crt&sslkey=certs/client.maxroach.key&sslcert=certs/client.maxroach.crt")

 	if err != nil {
    	log.Fatal("error connecting to the database: ", err)
	}

	// Run a transfer in a transaction.
	err = crdb.ExecuteTx(context.Background(), db, nil, func(tx *sql.Tx) error {
    	return transferFunds(tx, 1 /* from acct# */, 2 /* to acct# */, 100 /* amount 	*/)
 	})
	 if err == nil {
    	fmt.Println("Success")
	 } else {
    	log.Fatal("error: ", err)
	}
}

在默认的隔离级别SERIALIZABLE下,因读写冲突导致事务执行失败,需要用户主动地重新提交事务。用户也实现通用的retry函数在事务内部重新执行事务。

在Golang环境下,CockroachDB的retry函数位于CockroachDB Go客户端的crdb包中,用户需要将相关库克隆到$GOPATH当中:

mkdir -p $GOPATH/src/github.com/cockroachdb
cd $GOPATH/src/github.com/cockroachdb
git clone git@github.com:cockroachdb/cockroach-go.git

执行:

go run txn-sample.go

输出:

Success

执行查询:

cockroach sql --insecure -e 'SELECT id, balance FROM accounts' --database=bank
+----+---------+
| id | balance |
+----+---------+
|  1 |     900 |
|  2 |     350 |
+----+---------+
(2 rows)

使用GORM框架

步骤 1: 安装GORM

go get -u github.com/lib/pq # dependency
go get -u github.com/jinzhu/gorm

步骤 2: 启动节点

以非安全模式启动节点:

cockroach start --insecure --store=hello-1 --host=localhost

步骤 3: 创建用户

执行cockroach user命令创建maxroach用户:

cockroach user set maxroach --insecure

步骤 4: 创建数据库并授权

以root用户启动内置的SQL客户端,创建bank数据库并授权maxroach用户。

cockroach sql --insecure -e 'CREATE DATABASE bank'
cockroach sql --insecure -e 'GRANT ALL ON DATABASE bank TO maxroach'

步骤 5: 编写执行Go代码

下述Go代码中,代码db.AutoMigrate(&Account{}将根据Account模型创建accounts表:

package main

import (
	"fmt"
	"log"
 	"github.com/jinzhu/gorm"
	 _ "github.com/jinzhu/gorm/dialects/postgres"
)

type Account struct {
	ID      int `gorm:"primary_key"`
	Balance int
}

func main() {
 	//非安全模式
	const addr = "postgresql://maxroach@localhost:26257/bank?sslmode=disable"
	//安全模式
 	//const addr = "postgresql://maxroach@localhost:26257/bank?ssl=true&sslmode=require&sslrootcert=certs/ca.crt&sslkey=certs/client.maxroach.key&sslcert=certs/client.maxroach.crt"

	db, err := gorm.Open("postgres", addr)
	if err != nil {
    	log.Fatal(err)
	}
	defer db.Close()

	db.AutoMigrate(&Account{})
	db.Create(&Account{ID: 1, Balance: 1000})
	db.Create(&Account{ID: 2, Balance: 250})

	var accounts []Account
	db.Find(&accounts)
	fmt.Println("Initial balances:")
	for _, account := range accounts {
        fmt.Printf("%d %d\n", account.ID, account.Balance)
	}
}

执行:

go run gorm-basic-sample.go

输出:

Initial balances:
1 1000
2 250

执行查询:

cockroach sql --insecure -e 'SELECT id, balance FROM accounts' --database=bank
+----+---------+
| id | balance |
+----+---------+
|  1 |    1000 |
|  2 |     250 |
+----+---------+
(2 rows)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值