Skip to content

Commit 4d1c59b

Browse files
committed
[doc] update
1 parent a39b99c commit 4d1c59b

File tree

5 files changed

+159
-198
lines changed

5 files changed

+159
-198
lines changed

README.md

Lines changed: 73 additions & 196 deletions
Original file line numberDiff line numberDiff line change
@@ -1,244 +1,121 @@
11
# Postgresql Storage
22

3+
# 一、这是什么
4+
以PostgreSQL为存储引擎的[Storage](https://github.com/storage-lock/go-storage)实现,当前仓库为比较底层的存储层实现,你可以与[storage-lock](https://github.com/storage-lock/go-storage-lock)结合使用,或者这个项目[PostgreSQL-locks](https://github.com/storage-lock/go-postgresql-storage)里专门封装提供了一些PostgreSQL锁相关的更易用友好的API。
5+
6+
7+
# 二、安装依赖
38

49
```bash
510
go get -u github.com/storage-lock/go-postgresql-storage
611
```
712

13+
# 三、API Examples
814

15+
## 3.1 从DSN创建PostgreSQLStorage
916

10-
## 3.2 Postgresql
11-
12-
### 3.2.1 快速开始
17+
在Golang的世界中连接数据库最常见的就是DSN,下面的例子演示了如何从一个DSN创建PostgreSQLStorage:
1318

1419
```go
1520
package main
1621

1722
import (
1823
"context"
1924
"fmt"
20-
storage_lock "github.com/storage-lock/go-storage-lock"
21-
"strings"
22-
"sync"
23-
"time"
25+
26+
postgresql_storage "github.com/storage-lock/go-postgresql-storage"
2427
)
2528

2629
func main() {
2730

28-
// Docker启动Postgresql:
29-
// docker run -d --name storage-lock-postgres -p 5432:5432 -e POSTGRES_PASSWORD=UeGqAm8CxYGldMDLoNNt postgres:14
31+
// 使用一个DSN形式的数据库连接字符串创建ConnectionManager
32+
testDsn := "host=127.0.0.1 user=postgres password=UeGqAm8CxYGldMDLoNNt port=5432 dbname=postgres sslmode=disable"
33+
connectionManager := postgresql_storage.NewPostgreSQLConnectionGetterFromDSN(testDsn)
3034

31-
// DSN的写法参考驱动的支持:https://github.com/lib/pq
32-
dsn := "host=192.168.128.206 user=postgres password=UeGqAm8CxYGldMDLoNNt port=5432 dbname=postgres sslmode=disable"
33-
34-
// 这个是最为重要的,通常是要锁住的资源的名称
35-
lockId := "must-serial-operation-resource-foo"
36-
37-
// 第一步创建一把分布式锁
38-
lock, err := storage_lock.NewPostgreSQLStorageLock(context.Background(), lockId, dsn)
35+
// 然后从这个ConnectionManager创建PostgreSQL Storage
36+
options := postgresql_storage.NewPostgreSQLStorageOptions().SetConnectionManager(connectionManager)
37+
storage, err := postgresql_storage.NewPostgreSQLStorage(context.Background(), options)
3938
if err != nil {
40-
fmt.Printf("[ %s ] Create Lock Failed: %v\n", time.Now().Format("2006-01-02 15:04:05"), err)
41-
return
39+
panic(err)
4240
}
41+
fmt.Println(storage.GetName())
42+
43+
}
44+
45+
```
46+
47+
48+
## 3.2 从连接属性(ip、端口、用户名、密码等等)中创建PostgreSQLStorage
49+
50+
或者你的配置文件中存放的并不是DSN,而是零散的几个连接属性,下面是一个创建PostgreSQLStorage的例子:
51+
52+
```go
53+
package main
4354

44-
// 第二步使用这把锁,这里就模拟多个节点竞争执行的情况,他们会线程安全的往resource里写数据
45-
resource := strings.Builder{}
46-
var wg sync.WaitGroup
47-
for i := 0; i < 10; i++ {
48-
workerId := fmt.Sprintf("worker-%d", i)
49-
wg.Add(1)
50-
go func() {
51-
defer wg.Done()
52-
53-
// 获取锁
54-
err := lock.Lock(context.Background(), workerId)
55-
if err != nil {
56-
fmt.Printf("[ %s ] workerId = %s, lock failed: %v \n", time.Now().Format("2006-01-02 15:04:05"), workerId, err)
57-
return
58-
}
59-
// 退出的时候释放锁
60-
defer func() {
61-
err := lock.UnLock(context.Background(), workerId)
62-
if err != nil {
63-
fmt.Printf("[ %s ] workerId = %s, unlock failed: %v \n", time.Now().Format("2006-01-02 15:04:05"), workerId, err)
64-
return
65-
}
66-
}()
67-
68-
// 假装有耗时的操作
69-
fmt.Printf("[ %s ] workerId = %s, begin write resource \n", time.Now().Format("2006-01-02 15:04:05"), workerId)
70-
time.Sleep(time.Second * 3)
71-
// 接下来是操作竞态资源
72-
resource.WriteString(workerId)
73-
fmt.Printf("[ %s ] workerId = %s, write resource done \n", time.Now().Format("2006-01-02 15:04:05"), workerId)
74-
resource.WriteString("\n")
75-
76-
}()
55+
import (
56+
"context"
57+
"fmt"
58+
59+
postgresql_storage "github.com/storage-lock/go-postgresql-storage"
60+
)
61+
62+
func main() {
63+
64+
// 使用一个DSN形式的数据库连接字符串创建ConnectionManager
65+
host := "127.0.0.1"
66+
port := uint(5432)
67+
username := "postgres"
68+
passwd := "UeGqAm8CxYGldMDLoNNt"
69+
database := "postgres"
70+
connectionManager := postgresql_storage.NewPostgreSQLConnectionGetter(host, port, username, passwd, database)
71+
72+
// 然后从这个ConnectionManager创建PostgreSQL Storage
73+
options := postgresql_storage.NewPostgreSQLStorageOptions().SetConnectionManager(connectionManager)
74+
storage, err := postgresql_storage.NewPostgreSQLStorage(context.Background(), options)
75+
if err != nil {
76+
panic(err)
7777
}
78-
wg.Wait()
79-
80-
// 观察最终的输出是否和日志一致
81-
fmt.Printf("[ %s ] Resource: \n", time.Now().Format("2006-01-02 15:04:05"))
82-
fmt.Println(resource.String())
83-
84-
// Output:
85-
// [ 2023-03-13 00:29:37 ] workerId = worker-3, begin write resource
86-
// [ 2023-03-13 00:29:40 ] workerId = worker-3, write resource done
87-
// [ 2023-03-13 00:29:40 ] workerId = worker-5, begin write resource
88-
// [ 2023-03-13 00:29:43 ] workerId = worker-5, write resource done
89-
// [ 2023-03-13 00:29:43 ] workerId = worker-8, begin write resource
90-
// [ 2023-03-13 00:29:46 ] workerId = worker-8, write resource done
91-
// [ 2023-03-13 00:29:46 ] workerId = worker-6, begin write resource
92-
// [ 2023-03-13 00:29:49 ] workerId = worker-6, write resource done
93-
// [ 2023-03-13 00:29:50 ] workerId = worker-2, begin write resource
94-
// [ 2023-03-13 00:29:53 ] workerId = worker-2, write resource done
95-
// [ 2023-03-13 00:29:56 ] workerId = worker-0, begin write resource
96-
// [ 2023-03-13 00:29:59 ] workerId = worker-0, write resource done
97-
// [ 2023-03-13 00:30:00 ] workerId = worker-1, begin write resource
98-
// [ 2023-03-13 00:30:03 ] workerId = worker-1, write resource done
99-
// [ 2023-03-13 00:30:04 ] workerId = worker-4, begin write resource
100-
// [ 2023-03-13 00:30:07 ] workerId = worker-4, write resource done
101-
// [ 2023-03-13 00:30:08 ] workerId = worker-9, begin write resource
102-
// [ 2023-03-13 00:30:11 ] workerId = worker-9, write resource done
103-
// [ 2023-03-13 00:30:14 ] workerId = worker-7, begin write resource
104-
// [ 2023-03-13 00:30:18 ] workerId = worker-7, write resource done
105-
// [ 2023-03-13 00:30:18 ] Resource:
106-
// worker-3
107-
// worker-5
108-
// worker-8
109-
// worker-6
110-
// worker-2
111-
// worker-0
112-
// worker-1
113-
// worker-4
114-
// worker-9
115-
// worker-7
78+
fmt.Println(storage.GetName())
11679

11780
}
11881

11982
```
12083

121-
### 3.2.2 详细配置
84+
85+
## 3.3 从sql.DB创建PostgreSQLStorage
86+
87+
或者现在你已经有从其它渠道创建的能够连接到PostgreSQL的sql.DB,则也可以从这个*sql.DB创建PostgreSQLStorage
12288

12389
```go
12490
package main
12591

12692
import (
12793
"context"
94+
"database/sql"
12895
"fmt"
129-
storage_lock "github.com/storage-lock/go-storage-lock"
130-
"strings"
131-
"sync"
132-
"time"
96+
97+
"github.com/storage-lock/go-storage"
98+
99+
postgresql_storage "github.com/storage-lock/go-postgresql-storage"
133100
)
134101

135102
func main() {
136103

137-
// Docker启动Postgresql:
138-
// docker run -d --name storage-lock-postgres -p 5432:5432 -e POSTGRES_PASSWORD=UeGqAm8CxYGldMDLoNNt postgres:14
139-
140-
// DSN的写法参考驱动的支持:https://github.com/lib/pq
141-
dsn := "host=192.168.128.206 user=postgres password=UeGqAm8CxYGldMDLoNNt port=5432 dbname=postgres sslmode=disable"
142-
143-
// 第一步先配置存储介质相关的参数,包括如何连接到这个数据库,连接上去之后锁的信息存储到哪里等等
144-
// 配置如何连接到数据库
145-
connectionGetter := storage_lock.NewPostgreSQLStorageConnectionGetterFromDSN(dsn)
146-
storageOptions := &storage_lock.PostgreSQLStorageOptions{
147-
// 数据库连接获取方式,可以使用内置的从DSN获取连接,也可以自己实现接口决定如何连接
148-
ConnectionGetter: connectionGetter,
149-
// 选择锁信息存放在哪个schema下,默认为public
150-
Schema: "public",
151-
// 锁的信息是存储在哪张表中的,不设置的话默认为storage_lock
152-
TableName: "storage_lock_table",
153-
}
154-
storage, err := storage_lock.NewPostgreSQLStorage(context.Background(), storageOptions)
104+
// 使用一个DSN形式的数据库连接字符串创建ConnectionManager
105+
testDsn := "host=127.0.0.1 user=postgres password=UeGqAm8CxYGldMDLoNNt port=5432 dbname=postgres sslmode=disable"
106+
db, err := sql.Open("postgres", testDsn)
155107
if err != nil {
156-
fmt.Println("Create Storage Failed: " + err.Error())
157-
return
108+
panic(err)
158109
}
110+
connectionManager := storage.NewFixedSqlDBConnectionManager(db)
159111

160-
// 第二步配置锁的参数,在上面创建的Storage的上创建一把锁
161-
lockOptions := &storage_lock.StorageLockOptions{
162-
// 这个是最为重要的,通常是要锁住的资源的名称
163-
LockId: "must-serial-operation-resource-foo",
164-
LeaseExpireAfter: time.Second * 30,
165-
LeaseRefreshInterval: time.Second * 5,
166-
VersionMissRetryTimes: 3,
167-
}
168-
lock := storage_lock.NewStorageLock(storage, lockOptions)
169-
170-
// 第三步开始使用锁,模拟多个节点竞争同一个锁使用的情况
171-
resource := strings.Builder{}
172-
var wg sync.WaitGroup
173-
for i := 0; i < 10; i++ {
174-
workerId := fmt.Sprintf("worker-%d", i)
175-
wg.Add(1)
176-
go func() {
177-
defer wg.Done()
178-
179-
// 获取锁
180-
err := lock.Lock(context.Background(), workerId)
181-
if err != nil {
182-
fmt.Printf("[ %s ] workerId = %s, lock failed: %v \n", time.Now().Format("2006-01-02 15:04:05"), workerId, err)
183-
return
184-
}
185-
// 退出的时候释放锁
186-
defer func() {
187-
err := lock.UnLock(context.Background(), workerId)
188-
if err != nil {
189-
fmt.Printf("[ %s ] workerId = %s, unlock failed: %v \n", time.Now().Format("2006-01-02 15:04:05"), workerId, err)
190-
return
191-
}
192-
}()
193-
194-
// 假装有耗时的操作
195-
fmt.Printf("[ %s ] workerId = %s, begin write resource \n", time.Now().Format("2006-01-02 15:04:05"), workerId)
196-
time.Sleep(time.Second * 3)
197-
// 接下来是操作竞态资源
198-
resource.WriteString(workerId)
199-
fmt.Printf("[ %s ] workerId = %s, write resource done \n", time.Now().Format("2006-01-02 15:04:05"), workerId)
200-
resource.WriteString("\n")
201-
202-
}()
112+
// 然后从这个ConnectionManager创建PostgreSQL Storage
113+
options := postgresql_storage.NewPostgreSQLStorageOptions().SetConnectionManager(connectionManager)
114+
storage, err := postgresql_storage.NewPostgreSQLStorage(context.Background(), options)
115+
if err != nil {
116+
panic(err)
203117
}
204-
wg.Wait()
205-
206-
// 观察最终的输出是否和日志一致
207-
fmt.Printf("[ %s ] Resource: \n", time.Now().Format("2006-01-02 15:04:05"))
208-
fmt.Println(resource.String())
209-
210-
// Output:
211-
// [ 2023-03-13 00:33:38 ] workerId = worker-0, begin write resource
212-
// [ 2023-03-13 00:33:41 ] workerId = worker-0, write resource done
213-
// [ 2023-03-13 00:33:42 ] workerId = worker-3, begin write resource
214-
// [ 2023-03-13 00:33:45 ] workerId = worker-3, write resource done
215-
// [ 2023-03-13 00:33:45 ] workerId = worker-6, begin write resource
216-
// [ 2023-03-13 00:33:48 ] workerId = worker-6, write resource done
217-
// [ 2023-03-13 00:33:49 ] workerId = worker-5, begin write resource
218-
// [ 2023-03-13 00:33:52 ] workerId = worker-5, write resource done
219-
// [ 2023-03-13 00:33:53 ] workerId = worker-2, begin write resource
220-
// [ 2023-03-13 00:33:56 ] workerId = worker-2, write resource done
221-
// [ 2023-03-13 00:33:57 ] workerId = worker-8, begin write resource
222-
// [ 2023-03-13 00:34:00 ] workerId = worker-8, write resource done
223-
// [ 2023-03-13 00:34:01 ] workerId = worker-4, begin write resource
224-
// [ 2023-03-13 00:34:04 ] workerId = worker-4, write resource done
225-
// [ 2023-03-13 00:34:04 ] workerId = worker-1, begin write resource
226-
// [ 2023-03-13 00:34:07 ] workerId = worker-1, write resource done
227-
// [ 2023-03-13 00:34:08 ] workerId = worker-9, begin write resource
228-
// [ 2023-03-13 00:34:11 ] workerId = worker-9, write resource done
229-
// [ 2023-03-13 00:34:11 ] workerId = worker-7, begin write resource
230-
// [ 2023-03-13 00:34:14 ] workerId = worker-7, write resource done
231-
// [ 2023-03-13 00:34:14 ] Resource:
232-
// worker-0
233-
// worker-3
234-
// worker-6
235-
// worker-5
236-
// worker-2
237-
// worker-8
238-
// worker-4
239-
// worker-1
240-
// worker-9
241-
// worker-7
118+
fmt.Println(storage.GetName())
242119

243120
}
244121

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
package main
2+
3+
import (
4+
"context"
5+
"fmt"
6+
7+
postgresql_storage "github.com/storage-lock/go-postgresql-storage"
8+
)
9+
10+
func main() {
11+
12+
// 使用一个DSN形式的数据库连接字符串创建ConnectionManager
13+
testDsn := "host=127.0.0.1 user=postgres password=UeGqAm8CxYGldMDLoNNt port=5432 dbname=postgres sslmode=disable"
14+
connectionManager := postgresql_storage.NewPostgreSQLConnectionGetterFromDSN(testDsn)
15+
16+
// 然后从这个ConnectionManager创建PostgreSQL Storage
17+
options := postgresql_storage.NewPostgreSQLStorageOptions().SetConnectionManager(connectionManager)
18+
storage, err := postgresql_storage.NewPostgreSQLStorage(context.Background(), options)
19+
if err != nil {
20+
panic(err)
21+
}
22+
fmt.Println(storage.GetName())
23+
24+
}
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
package main
2+
3+
import (
4+
"context"
5+
"fmt"
6+
7+
postgresql_storage "github.com/storage-lock/go-postgresql-storage"
8+
)
9+
10+
func main() {
11+
12+
// 使用一个DSN形式的数据库连接字符串创建ConnectionManager
13+
host := "127.0.0.1"
14+
port := uint(5432)
15+
username := "postgres"
16+
passwd := "UeGqAm8CxYGldMDLoNNt"
17+
database := "postgres"
18+
connectionManager := postgresql_storage.NewPostgreSQLConnectionGetter(host, port, username, passwd, database)
19+
20+
// 然后从这个ConnectionManager创建PostgreSQL Storage
21+
options := postgresql_storage.NewPostgreSQLStorageOptions().SetConnectionManager(connectionManager)
22+
storage, err := postgresql_storage.NewPostgreSQLStorage(context.Background(), options)
23+
if err != nil {
24+
panic(err)
25+
}
26+
fmt.Println(storage.GetName())
27+
28+
}

0 commit comments

Comments
 (0)