15

Command pattern can be used to implement Transactional behavior (and Undo).
But I could not find an example of these by googling. I could only find some trivial examples of a lamp that is switched on or off.
Where can I find a coding example (preferably in Java)of this/these behaviors implemented using the Command Pattern?

Ravindra babu
  • 37,698
  • 11
  • 250
  • 211
Jim
  • 18,826
  • 34
  • 135
  • 254

3 Answers3

25

In one of our projects, we have the following requirement:

  1. Create a record in DB.
  2. Call a service to update a related record.
  3. Call another service to log a ticket.

To perform this in a transactional manner, each operation is implemented as a command with undo operation. At the end of each step, the command is pushed onto a stack. If the operation fails at some step, then we pop the commands from the stack and call undo operation on each of the command popped out. The undo operation of each step is defined in that command implementation to reverse the earlier command.execute().

Hope this helps.

Vikdor
  • 23,934
  • 10
  • 61
  • 84
  • 1
    Not sure I follow.A transaction is rolledbacked.Is not composed of undo operations.How did you implement the atomic part with the command pattern? – Jim Aug 28 '12 at 06:29
  • 1
    In a database level transaction, each operation is a command with undo and redo operations. Upon rollback, the DBMS will call the undo operation to revert the changes made to the copy of the DB it held. We are simulating the same thing in a distributed transaction that spans across systems. Does this make sense now? – Vikdor Aug 28 '12 at 06:33
  • 1
    `revert the changes made to the copy of the DB it held`.So the command applies first to a copy of the data and not the actual data?I thought that it applied directly to data that is why you need `undo`.Your description is somewhat clear but I need a little more low level details if possible to see the big picture – Jim Aug 28 '12 at 06:37
  • No, the DBMS will make a copy of the data so that others will see the data without your changes (transaction isolation levels are about this only). When you commit, then the copy will be updated to the actual location so that everyone else gets to see your changes. The redo operation on a command is used during failure recovery in conjunction with checkpoints (DBMS concept worth reading once) – Vikdor Aug 28 '12 at 06:39
  • So in your example of your implementation which parts of data did you copy to emulate the transactional behavior?The whole data? – Jim Aug 28 '12 at 06:44
  • In a distributed transaction, the modifications are done to the actual copies and hence you need a specific implementation of what an undo would mean. In our case, the undo operation for the service call (step2) is to issue another update that reverts the state of the record to previous values and that for the command that logs a ticket is to cancel it. – Vikdor Aug 28 '12 at 06:48
3
public final class Ping implements Callable<Boolean> {

  private final InetAddress peer;

  public Ping(final InetAddress peer) {
    this.peer = peer;
  }

  public Boolean call() {
    /* do the ping */
    ...
  }
}
...
final Future<Boolean> result
    = executorService.submit(new Ping(InetAddress.getByName("google.com")));
System.out.println("google.com is " + (result.get() ? "UP" : "DOWN"));
obataku
  • 29,212
  • 3
  • 44
  • 57
  • @Jim the Wikipedia article on the pattern mentions explicitly the following... "*A typical, general-purpose thread pool class might have a public `addTask` method that adds a work item to an internal queue of tasks waiting to be done. ... The items in the queue are command objects. Typically these objects implement a common interface such as `java.lang.Runnable` that allows the thread pool to execute the command even though the thread pool class itself was written without any knowledge of the specific tasks for which it would be used.*" – obataku Aug 28 '12 at 06:26
  • @Jim this is such an example in Java except using `Callable` as opposed to `Runnable` in conjunction with an [`ExecutorService`](http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/ExecutorService.html). A similar such example can be seen in the discussion regarding the Wikipedia article itself [here](http://en.wikipedia.org/wiki/Talk%3ACommand_pattern#Python_examples). – obataku Aug 28 '12 at 06:27
  • But I am asking for an example of specific application of the pattern.You have provided a gereral example of the pattern though – Jim Aug 28 '12 at 06:30
  • @Jim in general any `Runnable` will fulfill the command pattern. e.g. `class ExitTask implements Runnable { public void run() { System.exit(0); } }` – obataku Aug 28 '12 at 06:36
  • Perhaps I am misreading your answer but my question in the OP is, how to use the command pattern (with Java example) to implement transactional behavior. – Jim Aug 28 '12 at 06:42
  • @Jim indeed I was. I thought you were requesting a general Java example of the command pattern :-p – obataku Aug 28 '12 at 06:43
2

Command Patterns are used in a lot of places.

  1. Of course what you see everywhere is a very trivial example of GUI Implementation, switches. It is also used extensively is game development. With this pattern the user can configure his buttons on screen as well.
  2. It is used in Networking as well, if a command has to be passed to the other end.
  3. When the programmers want to store all the commands executed by the user, e.g. sometimes a game lets you replay the whole level.
  4. It is used to implement callbacks.

Here is a site which provides as example of command pattern used for callback. http://www.javaworld.com/article/2077569/core-java/java-tip-68--learn-how-to-implement-the-command-pattern-in-java.html?page=2

  1. Here's another link which shows command pattern with database. The code is in C#. http://www.codeproject.com/Articles/154606/Command-Pattern-at-Work-in-a-Database-Application
Ekta
  • 338
  • 2
  • 9
  • 26