Support for "Undo Method Calls" in JVM
Is there any way to undo the effects of a method call in Java? I am trying to solve the following problem. I have a set of Java Objects, Lets call them object1, object2 etc. In my program I call the methods in these objects in the following order:
...
o开发者_如何学编程bject1.method1(); // I assume JVM knows the internal state before and after this call
object2.method1();
object1.method2(); ...
I want to achieve the initial state of the program, without having to know myself what the method calls actually did. Does JVM allow me to get back to the state, before object1.method1() was called?
I understand that this means I need to do the following:
...
object1.UNDOmethod2();
object2.UNDOmethod1();
object1.UNDOmethod1();
...
But I am looking for a solution without having to write undo methods myself? I assume JVM would have the information to do this.. is this possible?
Thanks a million.
Consider using a Java implementation of Software Transactional Memory, such as Deuce STM. Concretely, Deuce relies on using Java instrumentation. If you can change your implementation to modify only a single data structure as a result of several method calls, consider using Transactional Maps from Apache.
The short answer is no. The JVM does not provide automated checkpoints of state that can be rolled back.
You could look at Continuations as a way to achieve this, though. You could then explicitly capture the program state between each method call and then roll back to the continuation that represents the historic state when you need to undo. See the following resources for more information about continuations in Java:
- Discussion about RIFE Continuations at Artima
- Experimental Continuations in the JVM
I think this is not possible. Also, there are things that you simply can't undo: side effects. For example a system.out.println("hello world!")
: once the JVM has executed that, you can't possibly undo it.
I think that you may want to undo are the changes to your data model (or values) that occurred after executing some method. In that case you may want to use the Command patterns and/or the Memento (or a combination of both).
You can do this with Spring Transaction or JTA. However I don't see this as a simple answer. Instead I would use the following approach.
if(object1.isOkay1() && object2.isOkay2()) {
object1.perform1();
object2.perform2();
} else {
// something went wrong.
}
perform1() and perform2() cannot throw an error or be rolled back.
精彩评论