示例#1
0
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)
}
示例#2
0
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
	})
}
示例#3
0
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()
}
示例#4
0
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)
}
示例#5
0
文件: string.go 项目: XuHuaiyu/tidb
// 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)
}
示例#6
0
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)
	}
}
示例#7
0
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)
}
示例#8
0
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"))
}