Created
April 4, 2020 05:38
-
-
Save ota42y/06c4e72f35e7aead7e14819a62b8cfbf to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package main | |
import ( | |
"fmt" | |
"math/rand" | |
"time" | |
"github.com/DATA-DOG/go-txdb" | |
"github.com/jinzhu/gorm" | |
_ "github.com/jinzhu/gorm/dialects/postgres" // Use PostgreSQL in gorm | |
) | |
func main() { | |
dial := fmt.Sprintf("postgres://%s:%s@%s:%s/%s?sslmode=%s&statement_timeout=2000", "gorm", "gorm", "localhost", "15432", "test1", "disable") | |
{ | |
conn, err := gorm.Open("postgres", dial) | |
if err != nil { | |
panic(err) | |
} | |
conn.AutoMigrate(&User{}) | |
if err := conn.Close(); err != nil { | |
panic(err) | |
} | |
} | |
{ | |
name := RandStringRunes(100) | |
conn1, err := gorm.Open("postgres", dial) | |
if err != nil { | |
panic(err) | |
} | |
conn2, err := gorm.Open("postgres", dial) | |
if err != nil { | |
panic(err) | |
} | |
err = testExec(conn1, conn2, name) | |
fmt.Println(err) | |
if err := conn1.Close(); err != nil { | |
panic(err) | |
} | |
if err := conn2.Close(); err != nil { | |
panic(err) | |
} | |
} | |
fmt.Println("conn3, conn4") | |
{ | |
name := RandStringRunes(100) | |
conn3, err := gorm.Open("postgres", dial) | |
if err != nil { | |
panic(err) | |
} | |
conn4, err := gorm.Open("postgres", dial) | |
if err != nil { | |
panic(err) | |
} | |
conn3 = conn3.Begin() | |
conn4 = conn4.Begin() | |
err = testExec(conn3, conn4, name) // conn3 wait lock so we got timeout error | |
fmt.Println(err) | |
if err := conn3.Rollback().Error; err != nil { | |
panic(err) | |
} | |
if err := conn4.Rollback().Error; err != nil { | |
panic(err) | |
} | |
if err := conn3.Close(); err != nil { | |
panic(err) | |
} | |
if err := conn4.Close(); err != nil { | |
panic(err) | |
} | |
} | |
fmt.Println("txdb") | |
{ | |
dbname := "postgreql_txdb" | |
txdb.Register(dbname, "postgres", dial) | |
dialect, ok := gorm.GetDialect("postgres") | |
if !ok { | |
panic(fmt.Errorf("dialect not exist")) | |
} | |
gorm.RegisterDialect(dbname, dialect) | |
name := RandStringRunes(100) | |
conn5, err := gorm.Open(dbname, "conn1") | |
if err != nil { | |
panic(err) | |
} | |
conn6, err := gorm.Open(dbname, "conn2") | |
if err != nil { | |
panic(err) | |
} | |
err = testExec(conn5, conn6, name) | |
fmt.Println(err) // timeout | |
if err := conn5.Close(); err != nil { | |
panic(err) | |
} | |
if err := conn6.Close(); err != nil { | |
panic(err) | |
} | |
} | |
fmt.Println("end") | |
} | |
func testExec(conn1 *gorm.DB, conn2 *gorm.DB, name string) error { | |
err := conn1.Save(&User{Name: name}).Error | |
if err != nil { | |
panic(err) // should be always succeed | |
} | |
err = conn2.Save(&User{Name: name}).Error | |
if err != nil { | |
fmt.Println("save failed") | |
return err | |
} | |
return nil | |
} | |
// https://stackoverflow.com/questions/22892120/how-to-generate-a-random-string-of-a-fixed-length-in-go | |
func init() { | |
rand.Seed(time.Now().UnixNano()) | |
} | |
var letterRunes = []rune("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ") | |
func RandStringRunes(n int) string { | |
b := make([]rune, n) | |
for i := range b { | |
b[i] = letterRunes[rand.Intn(len(letterRunes))] | |
} | |
return string(b) | |
} | |
type User struct { | |
gorm.Model | |
Name string `json:"name" gorm:"unique;not null"` | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment