tidis
tidis copied to clipboard
Question: Multi/exec transaction behavior
See the below example where I initiated a transaction with setting two hash values. First one successful and 2nd failed. I thought a transaction would roll back 1st operation because 2nd failed. but that's not the case.
127.0.0.1:5379> multi
OK
127.0.0.1:5379> hsetnx key1 field3 val3
QUEUED
127.0.0.1:5379> hsetnx key1 field1 val2
QUEUED
127.0.0.1:5379> exec
1) (integer) 1
2) (integer) 0
127.0.0.1:5379> hget key1 field3
"val3"
127.0.0.1:5379>
No. I think hsetnx return 0 is not a failure. multi/exec command behave gurantee all command executed in atomic without any error.
hsetnx key1 field1 val2 returned 0 because field1 already exist. So I guess it executes atomically but doesn't roll-back previous operation if subsequent failed.
hsetnx return 0 is not error, it just return a value 0, we treat it as normal. multi/exec acts the same as redis.
yes, it seems redis doesn't honor nx when multi/exec used. As you can see below, the initial value for key1 is val1 and when set to val2 with NX, it should have failed. Without multi/exec, it honors NX
Multi/Exec:
> multi
OK
> set key1 val1 nx
QUEUED
> exec
1) OK
> get key1
"val1"
> multi
OK
> set key1 val2 nx
QUEUED
> exec
1) OK
> get key1
"val2"
Here is without multi/exec:
> set key1 val1 nx
OK
> get key1
"val1"
> set key1 val2 nx
(nil)
> get key1
"val1"
My use-case is insert two key-val pair atomically and rollback if either one fails.
e.g .
set hash1 token1 NX
set token1 val1 NX
now if I try to insert either hash1 or token1 as a key, it should roll back
e.g. below hash2 toke1 would be successful but token1 val2 should fail which means it should roll back hash2 token1 as well.
set hash2 token1 NX
set token1 val2 NX
May be I can modify tidis code to add a custom function for this behavior.
@yongman can I consider return 0 is failed operation? It may not be an error but data are not stored.
127.0.0.1:5379> hsetnx k1 f1 v1
(integer) 1
127.0.0.1:5379> hsetnx k1 f1 v1
(integer) 0
127.0.0.1:5379> hsetnx k1 f2 v1
(integer) 1
127.0.0.1:5379> hsetnx k1 f2 v1
(integer) 0
I think ERR will be rollbacked, and the value returned should be handled in some logical level code other than in a database.
Of cause you can use your own version of tidis for your own use case.
For your case, I think tidis could add another group commands begin/commit/rollback, start a new transaction in begin other than start a new transaction in exec, return execute value other than QUEUED, so you can choose to commit or rollback in your logic.
Please refer to https://github.com/tidb-incubator/tidis