
Atomic procedures handle the concurrency, it's add a lock to the resource.
If two users access to the same resource at the same time, with the parameter `times` (default value 5) we can determine how many time retry to modify the resource, until the lock is release.

[cols="1m,5"]
|===
| CALL apoc.atomic.add(node/relationship, "property", number, [times]) YIELD oldValue, newValue  | adds the number to the value of the property
| CALL apoc.atomic.subtract(node/relationship, "property", number, [times]) YIELD oldValue, newValue | subtracts the number to the value of the property
| CALL apoc.atomic.concat(node/relationship, "property", "string", [times]) YIELD oldValue, newValue | concatenate the string to the property
| CALL apoc.atomic.insert(node/relationship, "property", position, object, [times]) YIELD oldValue, newValue | inserts the object in the chosen position of the array
| CALL apoc.atomic.remove(node/relationship, "property", position, [times]) YIELD oldValue, newValue | remove from the array the element to the position selected
| CALL apoc.atomic.update(node/relationship, "property", "expression", [times]) YIELD oldValue, newValue | update the property with the result of the expression
|===

== Atomic Examples

.add

Dataset

[source,cypher]
----
CREATE (p:Person {name:'Tom',age: 40})
----

We can add 10 to the property `age`

[source,cypher]
----
MATCH (n:Person {name:'Tom'})
CALL apoc.atomic.add(n,'age',10,5) YIELD oldValue, newValue
RETURN n
----

image::{img}/apoc.atomic.add.png[width=800]

.subtract

From the previous example we can go back to `age`: 40

[source,cypher]
----
MATCH (n:Person {name:'Tom'})
CALL apoc.atomic.subtract(n,'age',10,5) YIELD oldValue, newValue
RETURN n
----

.concat

Dataset

[source,cypher]
----
CREATE (p:Person {name:'Will',age: 35})
----

[source,cypher]
----
MATCH (p:Person {name:'Will',age: 35})
CALL apoc.atomic.concat(p,"name",'iam',5) YIELD newValue
RETURN p
----

image::{img}/apoc.atomic.concat.png[width=800]

.insert

Dataset

we add a propery `children` that is an array

[source,cypher]
----
CREATE (p:Person {name:'Tom', children: ['Anne','Sam','Paul']})
----

image::{img}/apoc.atomic.insert.png[width=800]

Now we add `Mary` to propery children at the position 2
[source,cypher]
----
MATCH (p:Person {name:'Tom'})
CALL apoc.atomic.insert(p,'children',2,'Mary',5) YIELD newValue
RETURN p
----

image::{img}/apoc.atomic.insert.result.png[width=800]

.remove

Dataset

[source,cypher]
----
CREATE (p:Person {name:'Tom', cars: ['Class A','X3','Focus']})
----

Now we remove the element `X3` which is at the position 1 from the array `cars`

[source,cypher]
----
MATCH (p:Person {name:'Tom'})
CALL apoc.atomic.remove(p,'cars',1,5) YIELD newValue
RETURN p
----

image::{img}/apoc.atomic.remove.png[width=800]

.update

Dataset

----
CREATE (p:Person {name:'Tom', salary1:1800, salary2:1500})
----

We want to update `salary1` with the result of an expression.
The expression always have to be referenced with the `n.` that refers to the node/rel passed as parameter.
If we rename our node/rel (as in the example above) we have anyway to refer to it in the expression as `n`.

[source,cypher]
----
MATCH (p:Person {name:'Tom'})
CALL apoc.atomic.update(p,'salary1','n.salary1*3 + n.salary2',5) YIELD newValue
RETURN p
----

image::{img}/apoc.atomic.update.png[width=800]
