# Are lua UDF functions transactional?

**URL:** <https://discuss.aerospike.com/t/are-lua-udf-functions-transactional/7441>\
**Category:** PHP Client Library\
**Created:** [May 16, 2020, 11:13am UTC](https://discuss.aerospike.com/t/are-lua-udf-functions-transactional/7441 "2020-05-16T11:13:00Z")\
**Posts on this page:** 12\
**Page:** 1

<div class="post-metadata">

**Author:** ![Miroslav\_Isikiyski](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.aerospike.com/miroslav_isikiyski/32/1434_2.png) [@Miroslav\_Isikiyski](https://discuss.aerospike.com/u/Miroslav_Isikiyski)\
**Post date:** [May 16, 2020, 11:13am UTC](https://discuss.aerospike.com/t/are-lua-udf-functions-transactional/7441/1 "2020-05-16T11:13:01Z")

</div>

Greetings!

I am using aerospike server as a response cache system. The system is multienvironment. The system does the following:

1. gets cached response for a user.
2. deletes the cache.
3. fills the cache with new response for the same user.

However, due to the multienvironment it can happen that after the cache is retrieved, the same user calls the system from another instance and the system fills the response again, but the response will be deleted if any slight lattency from the 1st query.

I implemented a UDF lua function, used in the apply() method - all works fine. My question is is this lua script transactional? Meaning that the mentioned above scenario won’t happen in case of multienv users. Here is the lua code: function get\_and\_delete(rec, bin) local response = rec[bin]

```
aerospike:remove(rec)

return response

```

end

Thanks in advance!

---

<div class="post-metadata">

**Author:** ![kporter](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.aerospike.com/kporter/32/515_2.png) [@kporter](https://discuss.aerospike.com/u/kporter)\
**Post date:** [May 19, 2020, 7:18pm UTC](https://discuss.aerospike.com/t/are-lua-udf-functions-transactional/7441/2 "2020-05-19T19:18:39Z")

</div>

Yes, it is transactional but also not very efficient.

As of [Aerospike 4.7.0.2](https://www.aerospike.com/download/server/notes.html#4.7.0.2) you can use the delete record operation which doesn’t require context switching to a LUA VM.

> [AER-6096] - (KVS) Added delete of entire record as an operation (e.g. to enable atomic read then delete).

For java this would be:

```auto
Record record = client.operate(params.writePolicy, key,
    Operation.get(),
    Operation.delete(),
    Operation.put(bin1),
    Operation.put(bin2),
    ...);

```

---

<div class="post-metadata">

**Author:** ![Miroslav\_Isikiyski](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.aerospike.com/miroslav_isikiyski/32/1434_2.png) [@Miroslav\_Isikiyski](https://discuss.aerospike.com/u/Miroslav_Isikiyski)\
**Post date:** [May 19, 2020, 7:49pm UTC](https://discuss.aerospike.com/t/are-lua-udf-functions-transactional/7441/3 "2020-05-19T19:49:49Z")

</div>

Thank you for the reply, however I tried the operate() method after going through the php client api but as I understand operate() requires write/increment as a first operation with optional post-read/delete actions?

---

<div class="post-metadata">

**Author:** ![kporter](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.aerospike.com/kporter/32/515_2.png) [@kporter](https://discuss.aerospike.com/u/kporter)\
**Post date:** [May 19, 2020, 7:53pm UTC](https://discuss.aerospike.com/t/are-lua-udf-functions-transactional/7441/4 "2020-05-19T19:53:28Z")

</div>

> [@Miroslav\_Isikiyski](#):
>
> I tried the operate() method after going through the php client api but as I understand operate() requires write/increment as a first operation with optional post-read/delete actions

No, I don’t believe that is the case, was there documentation that indicated this (which may need fixing) or did you test it?

Could you share a code snippet?

---

<div class="post-metadata">

**Author:** ![Miroslav\_Isikiyski](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.aerospike.com/miroslav_isikiyski/32/1434_2.png) [@Miroslav\_Isikiyski](https://discuss.aerospike.com/u/Miroslav_Isikiyski)\
**Post date:** [May 19, 2020, 8:38pm UTC](https://discuss.aerospike.com/t/are-lua-udf-functions-transactional/7441/5 "2020-05-19T20:38:14Z")

</div>

It is from here: [https://www.aerospike.com/docs/client/php/usage/kvs/write.html](https://www.aerospike.com/docs/client/php/usage/kvs/write.html) To combine multiple bin operations on a single record with optional post-write reads for the modified bin values:

```auto
$operations = [
  ["op" => Aerospike::OPERATOR_READ, "bin" => "test"],
  ["op" => Aerospike::OPERATOR_DELETE, "bin" => "test"],
];
$status = $db->operate($key, $operations, $returned);
if ($status == Aerospike::OK) {
  var_dump($returned); // display the age
}

```

I literally tested with the above snippet and I kept getting either timeout, or AS\_ERR\_UNKNOWN.

I can recheck again for sure, since you claim it should work - most probably was a missusage by me. Anyway - I would like to point out that the udf lua script actually works faster for me than the basic get and remove consecutive calls.

---

<div class="post-metadata">

**Author:** ![kporter](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.aerospike.com/kporter/32/515_2.png) [@kporter](https://discuss.aerospike.com/u/kporter)\
**Post date:** [May 19, 2020, 8:55pm UTC](https://discuss.aerospike.com/t/are-lua-udf-functions-transactional/7441/6 "2020-05-19T20:55:33Z")

</div>

If you want to delete the record, you shouldn’t need to specify a bin name. Similarly, if you wanted to read all the bins, you wouldn’t specify the bin name here either.

Actually the client dev just informed me that the delete operation doesn’t accept a bin argument, so that was probably causing an error (though I would have expected to see ‘PARAMETER’ and not ‘UNKNOWN’.)

---

<div class="post-metadata">

**Author:** ![Dylan\_W](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.aerospike.com/dylan_w/32/1314_2.png) [@Dylan\_W](https://discuss.aerospike.com/u/Dylan_W)\
**Post date:** [May 19, 2020, 9:25pm UTC](https://discuss.aerospike.com/t/are-lua-udf-functions-transactional/7441/7 "2020-05-19T21:25:52Z")

</div>

Hi @Miroslav_Isikiyski, Thanks for posting!

If you are looking to read a bin from the record, then delete the record in 1 call to operate, this should do the trick.

```auto
<?php

$HOST_ADDR = ("localhost");
$HOST_PORT = (3000);

echo "Connecting to the host\n";
$config = array("hosts" => array(array("addr" => $HOST_ADDR, "port" => $HOST_PORT)));
$db = new Aerospike($config, false);

echo "Writing a record in test.characters with PK=1234\n";
$digest = $db->getKeyDigest("test", "characters", 1234);
$key = $db->initKey("test", "characters", $digest, true);
$put_vals = array("email" => "freudian.circuits@hal-inst.org", "name" => "Perceptron");
$status = $db->put($key, $put_vals);

echo "Read the 'name' bin\n";
echo "Delete the record\n";
$operations = array(
    array("op" => Aerospike::OPERATOR_READ, "bin" => "name"),
    array("op" => Aerospike::OPERATOR_DELETE));
$res = $db->operate($key, $operations, $returned);
var_dump($returned);

$db->close();
?>

```

Hope this helps!

---

<div class="post-metadata">

**Author:** ![Miroslav\_Isikiyski](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.aerospike.com/miroslav_isikiyski/32/1434_2.png) [@Miroslav\_Isikiyski](https://discuss.aerospike.com/u/Miroslav_Isikiyski)\
**Post date:** [May 20, 2020, 6:45am UTC](https://discuss.aerospike.com/t/are-lua-udf-functions-transactional/7441/8 "2020-05-20T06:45:44Z")

</div>

Thank you both for the replies!

I used the same logic as Dylan’s example:

```auto
private function getAndDelete(string $userKey): string
    {
        $operations = [
            ["op" => \Aerospike::OPERATOR_READ, "bin" => 'testBIN'],
            ["op" => \Aerospike::OPERATOR_DELETE],
        ];

        $status = $this->aerospike->operate(
            $this->aerospike->initKey('testNS', 'testSET', $userKey), $operations, $returned
        );

        var_dump($returned);
        var_dump($status);

        if ($status != \Aerospike::OK || empty($returned)) {
            return '';
        }

        return $returned;
    }

```

And I get NULL for `$returned` and AS\_ERR\_PARAMETER for `$status`.

---

<div class="post-metadata">

**Author:** ![kporter](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.aerospike.com/kporter/32/515_2.png) [@kporter](https://discuss.aerospike.com/u/kporter)\
**Post date:** [May 20, 2020, 5:04pm UTC](https://discuss.aerospike.com/t/are-lua-udf-functions-transactional/7441/9 "2020-05-20T17:04:30Z")

</div>

Can you double check that you are running Aerospike 4.7.0.2 or later, also PARAMETER errors typically log a warning in the server logs, could you share that warning?

---

<div class="post-metadata">

**Author:** ![Miroslav\_Isikiyski](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.aerospike.com/miroslav_isikiyski/32/1434_2.png) [@Miroslav\_Isikiyski](https://discuss.aerospike.com/u/Miroslav_Isikiyski)\
**Post date:** [May 20, 2020, 5:47pm UTC](https://discuss.aerospike.com/t/are-lua-udf-functions-transactional/7441/10 "2020-05-20T17:47:27Z")

</div>

oohhh… sorry about not checking the version earlier… Yeah… on local environment I use 3.14

```auto
root@aerospike:/# asinfo -v build
3.14.1.4

```

On live we use even lower - 3.12.1 All makes sense now.

Anyway thank you for the fruitful discussion - I will stick to the UDF implementation I have and some day if we upgrade our aerospikes I will have the reference here as well 🙂

Thanks, Miroslav

---

<div class="post-metadata">

**Author:** ![kporter](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.aerospike.com/kporter/32/515_2.png) [@kporter](https://discuss.aerospike.com/u/kporter)\
**Post date:** [May 20, 2020, 6:17pm UTC](https://discuss.aerospike.com/t/are-lua-udf-functions-transactional/7441/11 "2020-05-20T18:17:14Z")

</div>

That is really old 🚂 the rebalance algorithms in 3.13 and earlier have a few serious design flaws. The flaws are rare but possible, and basically result in partitions thinking they are in sync when they aren’t (which basically means data loss). In 3.13 there is an operational switch to the new protocols where we redesigned the rebalance algorithms.

---

<div class="post-metadata">

**Author:** ![system](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.aerospike.com/system/32/2274_2.png) [@system](https://discuss.aerospike.com/u/system)\
**Post date:** [May 26, 2020, 6:17pm UTC](https://discuss.aerospike.com/t/are-lua-udf-functions-transactional/7441/12 "2020-05-26T18:17:14Z")

</div>

This topic was automatically closed 6 days after the last reply. New replies are no longer allowed.
