func (s *testKVSuite) TestInc(c *C) { defer testleak.AfterTest(c)() txn, err := s.s.Begin() c.Assert(err, IsNil) key := []byte("incKey") n, err := kv.IncInt64(txn, key, 100) c.Assert(err, IsNil) c.Assert(n, Equals, int64(100)) // Check transaction results err = txn.Commit() c.Assert(err, IsNil) txn, err = s.s.Begin() c.Assert(err, IsNil) n, err = kv.IncInt64(txn, key, -200) c.Assert(err, IsNil) c.Assert(n, Equals, int64(-100)) err = txn.Delete(key) c.Assert(err, IsNil) n, err = kv.IncInt64(txn, key, 100) c.Assert(err, IsNil) c.Assert(n, Equals, int64(100)) err = txn.Delete(key) c.Assert(err, IsNil) err = txn.Commit() c.Assert(err, IsNil) }
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) TestInc(c *C) { store, err := tidb.NewStore("memory://test/test_isolation") c.Assert(err, IsNil) defer store.Close() threadCnt := 4 ids := make(map[int64]struct{}, threadCnt*100) var m sync.Mutex var wg sync.WaitGroup wg.Add(threadCnt) for i := 0; i < threadCnt; i++ { go func() { defer wg.Done() for j := 0; j < 100; j++ { var id int64 err := kv.RunInNewTxn(store, true, func(txn kv.Transaction) error { var err1 error id, err1 = kv.IncInt64(txn, []byte("key"), 1) return err1 }) c.Assert(err, IsNil) m.Lock() _, ok := ids[id] ids[id] = struct{}{} m.Unlock() c.Assert(ok, IsFalse) } }() } wg.Wait() }
func (s *testKVSuite) TestConditionUpdate(c *C) { txn, err := s.s.Begin() c.Assert(err, IsNil) txn.Delete([]byte("b")) kv.IncInt64(txn, []byte("a"), 1) err = txn.Commit() c.Assert(err, IsNil) }
// Inc increments the integer value of a key by step, returns // the value after the increment. func (t *TxStructure) Inc(key []byte, step int64) (int64, error) { ek := t.encodeStringDataKey(key) // txn Inc will lock this key, so we don't lock it here. n, err := kv.IncInt64(t.txn, ek, step) if terror.ErrorEqual(err, kv.ErrNotExist) { err = nil } return n, errors.Trace(err) }
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) }
func (s *testKVSuite) TestIsolationInc(c *C) { defer testleak.AfterTest(c)() threadCnt := 4 ids := make(map[int64]struct{}, threadCnt*100) var m sync.Mutex var wg sync.WaitGroup wg.Add(threadCnt) for i := 0; i < threadCnt; i++ { go func() { defer wg.Done() for j := 0; j < 100; j++ { var id int64 err := kv.RunInNewTxn(s.s, true, func(txn kv.Transaction) error { var err1 error id, err1 = kv.IncInt64(txn, []byte("key"), 1) return err1 }) c.Assert(err, IsNil) m.Lock() _, ok := ids[id] ids[id] = struct{}{} m.Unlock() c.Assert(ok, IsFalse) } }() } wg.Wait() // delete txn, err := s.s.Begin() c.Assert(err, IsNil) defer txn.Commit() txn.Delete([]byte("key")) }