Coder Social home page Coder Social logo

See about nested transactions about ohm HOT 9 CLOSED

tribalvibes avatar tribalvibes commented on August 27, 2024
See about nested transactions

from ohm.

Comments (9)

cyx avatar cyx commented on August 27, 2024

Hello,

No plans. The main idea for the Ohm::Transaction model is to simply assist in simpler scenarios. For more complicated scenarios where dependencies and ordering is important, it's much simpler to script your transaction in Lua, and that's what we're doing in our applications.

from ohm.

tribalvibes avatar tribalvibes commented on August 27, 2024

Well, simpler is better of course, but only after the app works. I think I've given you a very simple and common scenario here above which it doesn't seem the currently proposed Ohm::Transaction mechanism can handle. Composition is cool but nesting is necessary when combining classes that need to commit state together but otherwise have no knowledge of each other.

Sure, we could write this in Lua or SQL for that matter but the whole point of Ohm is to reduce the complexity of our applications and adding another language to the chain is something we absolutely don't want to do. Although the layering may make the implementation simpler, it adds a lot of support overhead.

Rather, it's great if the Ohm layer provides an efficient transaction mechanism which may in part be implemented in Lua (we do not view Redis as an app dependency by the way; rather Ohm is supposed to be a more complete abstraction on the datastore.) And we should not need to code Lua to make simple multiobject and nested transactions work correctly with Ohm.

How about you illustrate the types of scenarios/use cases that the Ohm::Transaction mechanism is supposed to handle, and specifically the commit A -> commit B -> commit C scenario as above. Then we could proceed concretely. Seems like there would need to be a TransactionManager and some protocol for this to work but we want to keep the code of each persisted class 'simple'. Maybe you have a better idea?

from ohm.

cyx avatar cyx commented on August 27, 2024

Hmm well specifically nesting transactions isn't really something that happens in reality, even with SQL.

C needs B needs A is such an abstract example that it's not practical for us to think of a solution for it at this point.

It's much simpler to do reads, and then write all of the data gathered up, and that's it. If for some reason a different set of reads needs another set of reads, then why not just read them both in one block?

The reason for optimizing to Lua isn't a crutch either. Transactions that grow big doing optimistic locking have a very very poor performance profile. The reason for which is if you do 10 reads, and the transaction fails, then you have to do all of them all over again, and it is not deterministic when you'll finally get the chance to finally commit the transaction.

The way we see it, depending in your isolation levels, you have to use whichever fits the bill. Locking / CAS / Lua.

Thanks,
cyx

from ohm.

tribalvibes avatar tribalvibes commented on August 27, 2024

That all makes good sense, but what we're talking about is really a kind of lexical nesting, not sub-transactions:

If for some reason a different set of reads needs another set of reads, then why not just read them both in one block?

Let's say this is a request-based web application. It uses models composed from several modules/components/gems whatever. Let's say the models are 'transaction aware' to the level of Ohm::Transaction, so that e.g. A.op1 runs an Ohm::Transaction to do its updates and B.op2 similarly uses Ohm::Transaction for its updates which are atomic within the scope of each model. From the point of view of the application however, each model's updates must happen atomically together, i.e. either A&B commit or neither. From the developer's perspective we would like to have the transaction be 'automatically' request-scoped and ideally not even need anything explicit at the controller layer.

But even with explicitly starting the transaction in the controller, how would you propose composing this generally? While preserving the notion that A.op1 and B.op2 are each independently atomic, and we want to preserve the encapsulation of each model and not push model-specific logic into the controller. Further, each of these atomic model ops may invoke other model classes atomic ops, e.g. C.op3 unbenknownst to the controller. So illustrate how the composition could work with the current Ohm::Transaction sketch.

Also I'm not saying that doing it on the Lua side is bad, only that it should happen automatically from the perspective of the app developer.

from ohm.

cyx avatar cyx commented on August 27, 2024

So let's say module A, B, and C has a method txn that returns a transaction.

We can do this:

transaction = Transaction.new
transaction.append(A.txn)
transaction.append(B.txn)
transaction.append(C.txn)
transaction.commit(Ohm.redis)

All of the transactions at this point will happen all-or-nothing.

We're just against complecting transactions by making them aware of each other. As far as
appending them together and making them run in one go, that's what we targetted with the current design.

Thanks,
cyx

On Mar 26, 2012, at 2:17 PM, tribalvibes wrote:

That all makes good sense, but what we're talking about is really a kind of lexical nesting, not sub-transactions:

If for some reason a different set of reads needs another set of reads, then why not just read them both in one block?

Let's say this is a request-based web application. It uses models composed from several modules/components/gems whatever. Let's say the models are 'transaction aware' to the level of Ohm::Transaction, so that e.g. A.op1 runs an Ohm::Transaction to do its updates and B.op2 similarly uses Ohm::Transaction for its updates which are atomic within the scope of each model. From the point of view of the application however, each model's updates must happen atomically together, i.e. either A&B commit or neither. From the developer's perspective we would like to have the transaction be 'automatically' request-scoped and ideally not even need anything explicit at the controller layer.

But even with explicitly starting the transaction in the controller, how would you propose composing this generally? While preserving the notion that A.op1 and B.op2 are each independently atomic, and we want to preserve the encapsulation of each model and not push model-specific logic into the controller. Further, each of these atomic model ops may invoke other model classes atomic ops, e.g. C.op3 unbenknownst to the controller. So illustrate how the composition could work with the current Ohm::Transaction sketch.

Also I'm not saying that doing it on the Lua side is bad, only that it should happen automatically from the perspective of the app developer.


Reply to this email directly or view it on GitHub:
#49 (comment)

from ohm.

tribalvibes avatar tribalvibes commented on August 27, 2024

Right, not to overcomplixify this. I think the composition could work as-is or with a simple modification to the mechanism. We just want to avoid writing the block as you've done requiring the knowledge of all of the components' (and subcomponents') transactions to be centralised. Rather these could be pushed via a coordinator. We'll just follow our app needs and if it seems there should be a component or another layer for this we'll add it.
Cheers,
.tv/

from ohm.

cyx avatar cyx commented on August 27, 2024

@soveran last night pushed a change that ensures the order of execution of reads and writes. This in itself isn't the solution you're looking for in it's entirety, but it's a good starting point which doesn't incur any form of complexity or performance penalties.

With the latest master, you can compose transactions with the guarantee that previously appended transactions will always execute before transactions appended after.

Thanks,
cyx

from ohm.

frodsan avatar frodsan commented on August 27, 2024

@cyx Is this still valid or can be closed?

from ohm.

frodsan avatar frodsan commented on August 27, 2024

@soveran Same as #53. Ohm::Transaction has been removed from Ohm 2. Beyond that, apparently this issue was solved but not close it.

from ohm.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.