Files
chaisql/internal/database/database_test.go
2023-12-02 11:25:56 +04:00

70 lines
1.2 KiB
Go

package database_test
import (
"testing"
"time"
"github.com/chaisql/chai"
"github.com/chaisql/chai/internal/testutil/assert"
)
// See issue https://github.com/chaisql/chai/issues/298
func TestConcurrentTransactionManagement(t *testing.T) {
db, err := chai.Open(":memory:")
assert.NoError(t, err)
defer func() {
assert.NoError(t, db.Close())
}()
ch := make(chan struct{})
done := make(chan struct{})
go func() {
// 1. Start transaction T1.
tx, err := db.Begin(true)
assert.NoError(t, err)
// Start transaction T2.
ch <- struct{}{}
// Wait in case goroutine gets rescheduled.
time.Sleep(time.Millisecond)
// 3. Commit or rollback T1.
assert.NoError(t, tx.Rollback())
// Wait for T2 to finish and return.
<-ch
done <- struct{}{}
}()
go func() {
<-ch // wait for T1 to start.
// 2. Attempt to start transaction T2.
// Waits for T1 to finish.
tx, err := db.Begin(true)
assert.NoError(t, err)
assert.NoError(t, tx.Rollback())
ch <- struct{}{}
}()
r := make(chan bool)
go func() {
t := time.NewTimer(time.Second)
select {
case <-t.C:
r <- false
case <-done:
r <- true
}
if !t.Stop() {
<-t.C
}
}()
if ok := <-r; !ok {
t.Fatal("deadlock")
}
}