func (s *testKVSuite) TestBoltDBDeadlock(c *C) { d := localstore.Driver{ Driver: boltdb.Driver{}, } path := "boltdb_test" defer os.Remove(path) store, err := d.Open(path) c.Assert(err, IsNil) defer store.Close() kv.RunInNewTxn(store, false, func(txn kv.Transaction) error { txn.Set([]byte("a"), []byte("0")) kv.IncInt64(txn, []byte("a"), 1) kv.RunInNewTxn(store, false, func(txn kv.Transaction) error { txn.Set([]byte("b"), []byte("0")) kv.IncInt64(txn, []byte("b"), 1) return nil }) return nil }) kv.RunInNewTxn(store, false, func(txn kv.Transaction) error { n, err := kv.GetInt64(txn, []byte("a")) c.Assert(err, IsNil) c.Assert(n, Equals, int64(1)) n, err = kv.GetInt64(txn, []byte("b")) c.Assert(err, IsNil) c.Assert(n, Equals, int64(1)) return nil }) }
func (t *testIsolationSuite) TestMultiInc(c *C) { store, err := tidb.NewStore("memory://test/test_isolation") c.Assert(err, IsNil) defer store.Close() threadCnt := 4 incCnt := 100 keyCnt := 4 keys := make([][]byte, 0, keyCnt) for i := 0; i < keyCnt; i++ { keys = append(keys, []byte(fmt.Sprintf("test_key_%d", i))) } var wg sync.WaitGroup wg.Add(threadCnt) for i := 0; i < threadCnt; i++ { go func() { defer wg.Done() for j := 0; j < incCnt; j++ { err1 := kv.RunInNewTxn(store, true, func(txn kv.Transaction) error { for _, key := range keys { _, err2 := kv.IncInt64(txn, key, 1) if err2 != nil { return err2 } } return nil }) c.Assert(err1, IsNil) } }() } wg.Wait() for i := 0; i < keyCnt; i++ { err = kv.RunInNewTxn(store, false, func(txn kv.Transaction) error { for _, key := range keys { id, err1 := kv.GetInt64(txn, key) if err1 != nil { return err1 } c.Assert(id, Equals, int64(threadCnt*incCnt)) } return nil }) c.Assert(err, IsNil) } }
func (s *testKVSuite) TestIsolationMultiInc(c *C) { defer testleak.AfterTest(c)() threadCnt := 4 incCnt := 100 keyCnt := 4 keys := make([][]byte, 0, keyCnt) for i := 0; i < keyCnt; i++ { keys = append(keys, []byte(fmt.Sprintf("test_key_%d", i))) } var wg sync.WaitGroup wg.Add(threadCnt) for i := 0; i < threadCnt; i++ { go func() { defer wg.Done() for j := 0; j < incCnt; j++ { err := kv.RunInNewTxn(s.s, true, func(txn kv.Transaction) error { for _, key := range keys { _, err1 := kv.IncInt64(txn, key, 1) if err1 != nil { return err1 } } return nil }) c.Assert(err, IsNil) } }() } wg.Wait() err := kv.RunInNewTxn(s.s, false, func(txn kv.Transaction) error { for _, key := range keys { id, err1 := kv.GetInt64(txn, key) if err1 != nil { return err1 } c.Assert(id, Equals, int64(threadCnt*incCnt)) txn.Delete(key) } return nil }) c.Assert(err, IsNil) }