5

I know this is probably a bad way to ask this question. I was unable to find another question that addressed this.

The full question is this: We're producing a wrapper for a database and have two different viewpoints on managing data with the wrapper.

The first is that all changes made to a data object in code must be persisted in the database by calling a "save" method to actually save the changes. The other side is that these changes should be save as they are made, so if I change a property it's saved, I change another it's save as well.

What are the pros/cons of either choice and which is the "proper" way to manage the data?


To provide more information, we're using Node.js, and we're writing our own wrapper for Neo4j because we feel that the current one available is not complete, or have run into issues where we need more functionality. That being said, an example of the save as you go method (these examples are in Javascript):

// DB is defined as a connection to the database via HTTP(REST)
// "data" being an object that would represent new data
var node;
db.getNodeById(data.id, function(err, result) {
  node = result;
  // This function task an optional callback as a third parameter because in
  // in addition to setting the property on the "node" object it saves the
  // new value to the database by making an HTTP request.
  node.set("firstName", data.newFirstName);
  // auto saved as well
  node.set("lastName", data.newLastName);
  // end here as the node has already been updated with your changes.
});

And the opposing example would be:

// DB is defined as a connection to the database via HTTP(REST)
// "data" being an object that would represent new data
var node;
db.getNodeById(data.id, function(err, result) {
  node = result;
  // This changes the value for the node object only, nothing in the
  // database is changed.
  node.set("firstName", data.newFirstName);
  node.set("lastName", data.newLastName);
  // Save all your changes
  node.save();
});
6
  • The "save as you go" sounds extremely counterproductive, care to expand a bit on how that would work? Or perhaps provide some references that explain the approach?
    – yannis
    Apr 3, 2012 at 23:34
  • 2
    Also, sometimes if you don't want to lose data but don't want bad data either you can save to some sort of "staging area" then commit it, but whether and how this works is pretty application specific.
    – psr
    Apr 3, 2012 at 23:41
  • @YannisRizos I gave examples of both, as they would be used. I'm not quite sure exactly how to explain the process. I can think of it clearly but not really describe it.
    – izuriel
    Apr 3, 2012 at 23:59
  • @psr I think in practice that fits our final save action, all changes made exist on the object in memory until you call the save which will commit those changes to the database. But I disregarded the first part of you comment, these changes will be lost as soon as the object is deferenced in memory.
    – izuriel
    Apr 4, 2012 at 0:00
  • 2
    Considered using a standard O/R mapper?
    – user1249
    Apr 4, 2012 at 9:11

3 Answers 3

7

If you need transactions in your application, you will need to offer some kind of explicit "Save" option. If the applications don't need transactions, using a database (as opposed to, say, a NoSQL technology) may be redundant.

This also means that the "Save" operation should not be a method called on the mutated object. It should be a method on the transaction object, or the session.

1
  • 2
    +1. If you aren't grouping data together in a way that makes save-as-you-go impractical, you probably don't need a DB. Apr 4, 2012 at 0:12
3

I'd go for explicitly calling the save() method. Otherwise you'll get redundant saves when you don't need them. What if you have some sort of "onKeyUp" event. Do you really want to save as the user is typing each character? You'd be locked into that model.

In a multi-tiered app it's good for the code to be "aware" of the tier it's on. You don't need to hide it by having a bunch of state saving magic going on behind the scenes. Why is being "aware" good? Because hiding it is obfuscating how it works, not abstracting. (my opinion).

On another topic...... instead of Node.save(); use save(Node n); Actually save could still be a method of an object, just not the Node object. Why? Saving is not something that a node does. And this functionality literally is different depending on which tier your on, suggesting it's a behavior of the tier, not the node.

For example lets say you have Node.Draw(); This method doesn't even make sense on the serverside. Instead do something like GameBoard.Draw(Node n);

I'm probably getting too far off topic, but that's my 2 cents.

1
  • Thanks for you answer, despite going off topic I found it informative.
    – izuriel
    Apr 4, 2012 at 2:03
0

This post is old, but I had the same issue with respect to an inventory management project my company is building. It's a web-based PHP application with a PostgreSQL backend. We opted for the Save-As-You-Go approach as opposed to a Stage-and-Commit style (I borrowed the terms from version control because it's accurate here), because we want to offer feedback to the user immediately if there's an issue saving a record update to the actual database. Waiting until the script is closing and destructors are being called to finally discover there's an issue with saving all the user's changes was an unacceptable risk (given the complexity that our transactions can have). The drawback might be increased database traffic, but the user can know rather than hope that his changes have been made correctly. Those are the pros and cons I considered when answering this question for myself. Hopefully my answer will assist somebody else too.

2
  • this post is rather hard to read (wall of text). Would you mind editing it into a better shape?
    – gnat
    Aug 30, 2016 at 19:43
  • I'm not sure I like the conclusion that you've drawn. With the transactional approach that most database ORMs feature don't save changes as they are made. They instead offer explicit save mechanics and validate at that stage -- these validations give you plenty of information necessary to provide detailed error messages. The real key difference then is not your ability to provider errors, but instead how much data gets stored. I did not want to store any invalid data, and in your case partial storage may be acceptable, but it wasn't in mine. I asked this because my team thought I was crazy.
    – izuriel
    Nov 11, 2016 at 14:39

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.