Command like redis incr :atomic increment operations

` final Set set = new HashSet<>();

        for (int i = 0; i < number; i++) {
            Thread thread = new Thread(new Runnable() {
                @Override
                public void run() {
                    Record operate = client.operate(policy, key, Operation.add(bin), Operation.get());
                    int value = operate.getInt(bin.name);
                    set.add(value);
                }
            });
            thread.start();
        }`

the set.size() less than number,it‘s mean will get duplicate values

I want to increase the value of atom,In multithreaded environment,the code above some problems!

redis command: incr

http://redis.io/commands/incr

How I implement it in aerospike? use UDF?

Every language client for Aerospike includes an increment operation which will initialize the record if it does not exist. Why would you use UDF for this?

For example, the Python client’s aerospike.Client.increment

The docs for the various clients are linked to from here: http://www.aerospike.com/docs/client/

i use java and i don’t found native increment operation

I found the answer on github,use above code.

In the Java client documentation on our site there’s a link to the API reference where you would find it. It’s the ‘add’ operation.

I think you misunderstood what I mean

I need to increase the value of multi-threading and get to the increased

JAVA API [add] method can increase the value and can not be returned,so i use operate method add and return .

if the bin base value is 1 add i use multiple threads to add and get ,the return value maybe dirty data .

i test my code,the final value is no problem.

i mean like this:

base bin value is 1

 multi-threading 
{
    add "key" 1
    read "key" #Multiple threads may be return 3
 }

i wan’t thead-1 return 2,thead-2 return 3. current may be thead-1 reuturn 3 and thead-3 reutrn 3;

I want to give the user a non-repetition of id

I do not want to use uuid,

I want to use auto-incremented long value

Here is some example code that

  • increments a counter
  • decrements a counter
  • increments a counter and returns the new value
Key coounterKey = new Key(this.namespace, this.set, "my-counter");
/*
 * increment the counter by 1
 */
Bin counterBin = new Bin("some-counter", 1);
this.client.add(null, coounterKey, counterBin);
/*
 * increment the counter by 15
 */
counterBin = new Bin("some-counter", 15);
this.client.add(null, coounterKey, counterBin);
/*
* increment the counter by 1 and return the new value
*/
counterBin = new Bin("some-counter", 1);
Record record = this.client.operate(null, coounterKey, Operation.add(counterBin), Operation.get("some-counter"));
System.out.println("New value: " + record.getLong("some-counter"));
/*
 * decrement the counter by 5
 */
counterBin = new Bin("some-counter", -5);
this.client.add(null, coounterKey, counterBin);

I hope this helps

Thank you for your answer,

But I think in multiple threads,increments a counter and returns the new value,This result will be problems

It will not, because the increment operation is atomic. If you are using multi-ops you can tell it to both increment and read the value, so there is no time between those operations for something else to happen. You will perform both operations together. So you can increment a counter and get its value at that time, post-increment.

Does increment operation in Aerospike updates TTL of record?

Yes, increment will update a record’s TTL.

1 Like

Hello!

Can you show this code for php? A saw operation like “operate” and I want to know, if this is the same like INCR in Redis?

$key = $client->initKey("test", "users", 1234);
$operations = [
 ["op" => Aerospike::OPERATOR_INCR, "bin" => "age", "val" => 1],
 ["op" => Aerospike::OPERATOR_READ, "bin" => "age"],
];
$options = [Aerospike::OPT_TTL => 600];
$status = $client->operate($key, $operations, $returned, $options);
if ($status == Aerospike::OK) {
    var_dump($returned);
} else {
    echo "[{$client->errorno()}] ".$client->error();
}

Is the same like INCR in Redis? So is it atomic?

The code in your snippet looks correct for an increment of a bin, and a read of the new value.

The operate method in the PHP Client will cause all of the provided operations to be applied atomically. The value of the "age" bin will be incremented, and its new value will be returned to the client.

1 Like

Thanks!

So one more question - is in Aerospike function like bRPopLPush (in Redis)? I need to move element from List1 to List2. So it should be atomic. I mean there are 600 operations that will do the same, but I need that only one operation can do it and then return element back, and so on. Its like queue. Is this implementation in php language for this operation?

Aerospike does not currently have an equivalent atomic operation for either RPOPLPUSH or BRPOPLPUSH.

1 Like

So, is there any other ways to do it?

Presently, there isn’t an ‘operation’ to do such. You can write a UDF in LUA to do this atomically. UDF is currently the only solution for atomic multi-bin inter-bin operations.

Even if I will make pop operation? When I make pop operation - so it must be atomic operation. In manual there is: Atomic list operations only work against top level elements, not nested values (https://www.aerospike.com/docs/guide/cdt-list.html) So will it be atomic? And can I use it for queue?

That is saying that an operation such as list_pop is able to remove an element from the list, but not able to remove an element from a sublist.

For example

list = [1, 2, 3, [4, 5, 6]]
remove_by_index(list, -1) ## List = [1,2,3] now

But if list is:

list = [1, 2, 3, [4, 5, 6]]

With our current operations, you can not do something like remove a single element from the list stored in the last position of the main list. So, with our current operations, you cannot change list to:

[1, 2, 3, [4, 5]]

Using UDFs you can do these types of operations, and operate on multiple bins in the same record atomically.