Go-lang web app sync

I am writing a golang web application. The web application accesses the file system (read and write) and the sqlite3 database file.

Question 1: How to synchronize access to the file system in Go?

type DataObject struct { data []byte } func (*d DataObject) Write() { // // Synchronization ? // ioutil.WriteFile("file.name", d.data, 0644) // // Stop synchronization ? // } 

Question 2: Do I need to synchronize access to sqlite3 database files?

 type SqlObject struct { sqldata string } func (*s SqlObject) Store() error { // // Open the file, do I need some sort of synchronization? // con, err := sqlite.Open("database/datafile.db") if err != nil { return err } defer con.Close() err = con.Exec("INSERT INTO data(sqldata) values(?)", s.sqldata) if err != nil { return err } return nil } 

I am using the gosqlite3 driver ( http://code.google.com/p/gosqlite/ ).

+4
source share
4 answers

For files, it depends on your application. If you have only one goroutine writing file, you do not need to. If more than one, then it depends:

If you coordinate the various processes (programs), you can use flock (and probably it will not be fun).

If you coordinate several goroutines in your program, you can use mutexes , or you can see if you can re-organize the program, so that only one routine writes to a file and the rest send updates via channels.

For SQLite, I believe that the easiest way would be to simply open one sqlite connection and use it from different goroutines; although it supports several processes that open it immediately, and if your system does a lot of parallel reads, which can be faster (global locking is used for writing).

+7
source

Question 1

The "sync" package provides Lock and RWLock to synchronize access to resources in the usual way. Although there is nothing wrong with that, I like playing with idioms, so I can do something like this :

 package main import "fmt" func SyncFile(path string) chan<- func(string) { ch := make(chan func(string)) go func() { for process := range ch { process(path) } }() return ch } func main() { data := SyncFile("data.name") data <- func(path string) { fmt.Println(path) } } 

Then, if you only access the file through this funcs channel, access will be synchronized. It is reliable, but you may find something more efficient.

Question 2

The gosqlite3 driver is just a Go binding to libsqlite3, so the SQLite FAQ is applied (and it looks like you are aware of this). If you want both of them to be synchronized with each other, just wrap using SQLite inside the file access synchronization code.

+3
source

1) You must use read / write mutexes (in go std library). The code looks something like this:

 import "sync" // http://golang.org/pkg/sync/ const ( filename = "file.name" ) var globalFileLock sync.RWMutex type DataObject struct { data []byte } func (*d DataObject) Write() { globalFileLock.Lock() defer globalFileLock.Unlock() ioutil.WriteFile(filename, d.data, 0644) } func (*d DataObject) Read() { globalFileLock.RLock() defer globalFileLock.RUnlock() d.data = ioutil.ReadFile(filename) } 

2) Since you did not place the “import” section from your program, I do not know which sqlite driver you are using.

If you use the / sql database to open a database connection, the driver provides concurrency control between goroutines.

+2
source

I know his old question, but since I had the same “db lock” problem and the transaction resolved it for me, I thought I would say that here:

 db, err := sql.Open("sqlite3", db_path) if err != nil { log.Printf("Cannot connect to database: %s\n", err ) } defer db.Close() tx, _ := db.Begin() var value string err = tx.QueryRow("SELECT X FROM Y").Scan(&value) tx.Rollback() // or: tx.Commit() 
0
source

All Articles