Transactions in Redis with read operations











up vote
4
down vote

favorite
4












Using Redis, I want to perform an atomic sequence of commands, i.e. I need to guarantee that no other client will perform changes in the database while the sequence is being executed.



If I used write commands only, I could use MULTI and EXEC statements to assure atomicity using transactions. However, I would also like to use read commands in my transactions. Hence I cannot use MULTI, because read commands are also being queued!



Basically, in atomic manner, I need to do following:




  1. Read x from the database,

  2. Based on x, store f(x) to the database.


Both 1. and 2. should be part of a single, atomic transaction.



Is there a simple way how to do that?










share|improve this question
























  • You can try use Lua scripting: redis.io/commands/eval
    – OZ_
    Aug 26 '13 at 20:22

















up vote
4
down vote

favorite
4












Using Redis, I want to perform an atomic sequence of commands, i.e. I need to guarantee that no other client will perform changes in the database while the sequence is being executed.



If I used write commands only, I could use MULTI and EXEC statements to assure atomicity using transactions. However, I would also like to use read commands in my transactions. Hence I cannot use MULTI, because read commands are also being queued!



Basically, in atomic manner, I need to do following:




  1. Read x from the database,

  2. Based on x, store f(x) to the database.


Both 1. and 2. should be part of a single, atomic transaction.



Is there a simple way how to do that?










share|improve this question
























  • You can try use Lua scripting: redis.io/commands/eval
    – OZ_
    Aug 26 '13 at 20:22















up vote
4
down vote

favorite
4









up vote
4
down vote

favorite
4






4





Using Redis, I want to perform an atomic sequence of commands, i.e. I need to guarantee that no other client will perform changes in the database while the sequence is being executed.



If I used write commands only, I could use MULTI and EXEC statements to assure atomicity using transactions. However, I would also like to use read commands in my transactions. Hence I cannot use MULTI, because read commands are also being queued!



Basically, in atomic manner, I need to do following:




  1. Read x from the database,

  2. Based on x, store f(x) to the database.


Both 1. and 2. should be part of a single, atomic transaction.



Is there a simple way how to do that?










share|improve this question















Using Redis, I want to perform an atomic sequence of commands, i.e. I need to guarantee that no other client will perform changes in the database while the sequence is being executed.



If I used write commands only, I could use MULTI and EXEC statements to assure atomicity using transactions. However, I would also like to use read commands in my transactions. Hence I cannot use MULTI, because read commands are also being queued!



Basically, in atomic manner, I need to do following:




  1. Read x from the database,

  2. Based on x, store f(x) to the database.


Both 1. and 2. should be part of a single, atomic transaction.



Is there a simple way how to do that?







transactions redis atomicity






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Aug 26 '13 at 20:23

























asked Aug 26 '13 at 20:18









Tregoreg

4,04073052




4,04073052












  • You can try use Lua scripting: redis.io/commands/eval
    – OZ_
    Aug 26 '13 at 20:22




















  • You can try use Lua scripting: redis.io/commands/eval
    – OZ_
    Aug 26 '13 at 20:22


















You can try use Lua scripting: redis.io/commands/eval
– OZ_
Aug 26 '13 at 20:22






You can try use Lua scripting: redis.io/commands/eval
– OZ_
Aug 26 '13 at 20:22














1 Answer
1






active

oldest

votes

















up vote
9
down vote



accepted










There are two good solutions to your problem.



Option 1:



You need to issue a WATCH on the key you are reading from. Your transaction would look something like this:



WATCH x
x = GET x
MULTI
SET y, f(x)
EXEC


In this example, the write commands inside the multi block will be executed atomically, but only if the value of key x has not changed since WATCH was called. This is called an optimistic lock. If the value of x does change your application will get an error and will need to decide what to do next, which is likely to try again using the new value of x.



Option 2:



Redis now supports lua scripting, and lua scripts are executed atomically. If you can encapsulate your logic into a lua script, you can read your key, run your f(x) logic, and store the result, all atomically. This can be tricky or even a non-option depending on the logic you are performing. You might have to even do ugly hacks like pass values to lua by hardcoding them directly into the script you want redis to execute. That said, if you get it working this method should be reliable and performant, and you don't have to deal with handling EXEC failures.






share|improve this answer





















  • Option 1 is perfect for my needs as iterative retrying of the operation seems as a reasonable solution. Currently, my application logic is much more complex in comparison to the example I have provided, yet I'll definitely have a look at Lua. Thanks a lot!
    – Tregoreg
    Aug 29 '13 at 19:56











Your Answer






StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");

StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);

StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});

function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});


}
});














draft saved

draft discarded


















StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f18452335%2ftransactions-in-redis-with-read-operations%23new-answer', 'question_page');
}
);

Post as a guest















Required, but never shown

























1 Answer
1






active

oldest

votes








1 Answer
1






active

oldest

votes









active

oldest

votes






active

oldest

votes








up vote
9
down vote



accepted










There are two good solutions to your problem.



Option 1:



You need to issue a WATCH on the key you are reading from. Your transaction would look something like this:



WATCH x
x = GET x
MULTI
SET y, f(x)
EXEC


In this example, the write commands inside the multi block will be executed atomically, but only if the value of key x has not changed since WATCH was called. This is called an optimistic lock. If the value of x does change your application will get an error and will need to decide what to do next, which is likely to try again using the new value of x.



Option 2:



Redis now supports lua scripting, and lua scripts are executed atomically. If you can encapsulate your logic into a lua script, you can read your key, run your f(x) logic, and store the result, all atomically. This can be tricky or even a non-option depending on the logic you are performing. You might have to even do ugly hacks like pass values to lua by hardcoding them directly into the script you want redis to execute. That said, if you get it working this method should be reliable and performant, and you don't have to deal with handling EXEC failures.






share|improve this answer





















  • Option 1 is perfect for my needs as iterative retrying of the operation seems as a reasonable solution. Currently, my application logic is much more complex in comparison to the example I have provided, yet I'll definitely have a look at Lua. Thanks a lot!
    – Tregoreg
    Aug 29 '13 at 19:56















up vote
9
down vote



accepted










There are two good solutions to your problem.



Option 1:



You need to issue a WATCH on the key you are reading from. Your transaction would look something like this:



WATCH x
x = GET x
MULTI
SET y, f(x)
EXEC


In this example, the write commands inside the multi block will be executed atomically, but only if the value of key x has not changed since WATCH was called. This is called an optimistic lock. If the value of x does change your application will get an error and will need to decide what to do next, which is likely to try again using the new value of x.



Option 2:



Redis now supports lua scripting, and lua scripts are executed atomically. If you can encapsulate your logic into a lua script, you can read your key, run your f(x) logic, and store the result, all atomically. This can be tricky or even a non-option depending on the logic you are performing. You might have to even do ugly hacks like pass values to lua by hardcoding them directly into the script you want redis to execute. That said, if you get it working this method should be reliable and performant, and you don't have to deal with handling EXEC failures.






share|improve this answer





















  • Option 1 is perfect for my needs as iterative retrying of the operation seems as a reasonable solution. Currently, my application logic is much more complex in comparison to the example I have provided, yet I'll definitely have a look at Lua. Thanks a lot!
    – Tregoreg
    Aug 29 '13 at 19:56













up vote
9
down vote



accepted







up vote
9
down vote



accepted






There are two good solutions to your problem.



Option 1:



You need to issue a WATCH on the key you are reading from. Your transaction would look something like this:



WATCH x
x = GET x
MULTI
SET y, f(x)
EXEC


In this example, the write commands inside the multi block will be executed atomically, but only if the value of key x has not changed since WATCH was called. This is called an optimistic lock. If the value of x does change your application will get an error and will need to decide what to do next, which is likely to try again using the new value of x.



Option 2:



Redis now supports lua scripting, and lua scripts are executed atomically. If you can encapsulate your logic into a lua script, you can read your key, run your f(x) logic, and store the result, all atomically. This can be tricky or even a non-option depending on the logic you are performing. You might have to even do ugly hacks like pass values to lua by hardcoding them directly into the script you want redis to execute. That said, if you get it working this method should be reliable and performant, and you don't have to deal with handling EXEC failures.






share|improve this answer












There are two good solutions to your problem.



Option 1:



You need to issue a WATCH on the key you are reading from. Your transaction would look something like this:



WATCH x
x = GET x
MULTI
SET y, f(x)
EXEC


In this example, the write commands inside the multi block will be executed atomically, but only if the value of key x has not changed since WATCH was called. This is called an optimistic lock. If the value of x does change your application will get an error and will need to decide what to do next, which is likely to try again using the new value of x.



Option 2:



Redis now supports lua scripting, and lua scripts are executed atomically. If you can encapsulate your logic into a lua script, you can read your key, run your f(x) logic, and store the result, all atomically. This can be tricky or even a non-option depending on the logic you are performing. You might have to even do ugly hacks like pass values to lua by hardcoding them directly into the script you want redis to execute. That said, if you get it working this method should be reliable and performant, and you don't have to deal with handling EXEC failures.







share|improve this answer












share|improve this answer



share|improve this answer










answered Aug 27 '13 at 7:06









Carl Zulauf

33.8k22241




33.8k22241












  • Option 1 is perfect for my needs as iterative retrying of the operation seems as a reasonable solution. Currently, my application logic is much more complex in comparison to the example I have provided, yet I'll definitely have a look at Lua. Thanks a lot!
    – Tregoreg
    Aug 29 '13 at 19:56


















  • Option 1 is perfect for my needs as iterative retrying of the operation seems as a reasonable solution. Currently, my application logic is much more complex in comparison to the example I have provided, yet I'll definitely have a look at Lua. Thanks a lot!
    – Tregoreg
    Aug 29 '13 at 19:56
















Option 1 is perfect for my needs as iterative retrying of the operation seems as a reasonable solution. Currently, my application logic is much more complex in comparison to the example I have provided, yet I'll definitely have a look at Lua. Thanks a lot!
– Tregoreg
Aug 29 '13 at 19:56




Option 1 is perfect for my needs as iterative retrying of the operation seems as a reasonable solution. Currently, my application logic is much more complex in comparison to the example I have provided, yet I'll definitely have a look at Lua. Thanks a lot!
– Tregoreg
Aug 29 '13 at 19:56


















draft saved

draft discarded




















































Thanks for contributing an answer to Stack Overflow!


  • Please be sure to answer the question. Provide details and share your research!

But avoid



  • Asking for help, clarification, or responding to other answers.

  • Making statements based on opinion; back them up with references or personal experience.


To learn more, see our tips on writing great answers.





Some of your past answers have not been well-received, and you're in danger of being blocked from answering.


Please pay close attention to the following guidance:


  • Please be sure to answer the question. Provide details and share your research!

But avoid



  • Asking for help, clarification, or responding to other answers.

  • Making statements based on opinion; back them up with references or personal experience.


To learn more, see our tips on writing great answers.




draft saved


draft discarded














StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f18452335%2ftransactions-in-redis-with-read-operations%23new-answer', 'question_page');
}
);

Post as a guest















Required, but never shown





















































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown

































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown







Popular posts from this blog

Xamarin.iOS Cant Deploy on Iphone

Glorious Revolution

Dulmage-Mendelsohn matrix decomposition in Python