For a mysql connection I have a connection object and use a transaction mechanism connection.startTransaction()
, connection.commitTransaction()
, connection.rollbackTransaction()
.
For each startTransaction()
, there must always be either a call to commitTransaction()
or to rollbackTransaction()
. Missing such a call or calling both would break my transaction system.
So I use them in the following way:
boolean i_am_in_a_transaction=true;
try {
connection.startTransaction();
...
i_am_in_a_transaction=false;
connection.commitTransaction();
} finally {
if(i_am_in_a_transaction) {
connection.rollbackTransaction();
}
}
This ensures the declared calling order, but it is much effort, because I have to write this lines everywhere where I use transactions.
In C++ I would use a transaction object that checks in its destructor, if the commit()
function was called, and that otherwise calls rollback()
:
class Transaction {
public:
Transaction()
:am_in_transaction(false) {
}
~Transaction() {
if(_am_in_transaction) {
rollback();
}
}
void startTransaction() {
_am_in_transaction=true;
...start Transaction...
}
void commit() {
_am_in_transaction=false;
...commit Transaction...
}
void rollback() {
_am_in_transaction=false;
...rollback Transaction...
}
private:
bool _am_in_transaction;
}
This way I have the logic implemented at one place and can use it really simple:
Transaction my_transaction;
my_transaction.startTransaction;
...
my_transaction.commit();
This code is much simpler than the above java code with the try/finally block.
Is there a way to implement this behaviour in java without dedicating the logic to the caller and making him implement the try/finally block?
Something like a way to automatically call a function on scope exit would help me.