Note our transition before we apply it so that multiple processes don't run the

same transition and then all note that they ran it.


git-svn-id: https://samskivert.googlecode.com/svn/trunk@2200 6335cc39-0255-0410-8fd6-9bcaacd3b74c
This commit is contained in:
mdb
2007-08-21 21:39:28 +00:00
parent 2a9afb6bc5
commit d31d988945
@@ -24,9 +24,12 @@ import java.sql.Connection;
import java.sql.PreparedStatement; import java.sql.PreparedStatement;
import java.sql.ResultSet; import java.sql.ResultSet;
import java.sql.SQLException; import java.sql.SQLException;
import java.util.logging.Level;
import com.samskivert.io.PersistenceException; import com.samskivert.io.PersistenceException;
import static com.samskivert.Log.log;
/** /**
* Used to note that transitionary code has been run to migrate persistent data. This is especially * Used to note that transitionary code has been run to migrate persistent data. This is especially
* useful for data that one cannot examine to determine if it's been transitioned. * useful for data that one cannot examine to determine if it's been transitioned.
@@ -64,8 +67,28 @@ public class TransitionRepository extends SimpleRepository
throws PersistenceException throws PersistenceException
{ {
if (!isTransitionApplied(clazz, name)) { if (!isTransitionApplied(clazz, name)) {
trans.run();
noteTransition(clazz, name); noteTransition(clazz, name);
try {
trans.run();
} catch (PersistenceException e) {
try {
clearTransition(clazz, name);
} catch (PersistenceException pe) {
log.log(Level.WARNING, "Failed to clear failed transition [class=" + clazz +
", name=" + name + "].", pe);
}
throw e;
} catch (RuntimeException rte) {
try {
clearTransition(clazz, name);
} catch (PersistenceException pe) {
log.log(Level.WARNING, "Failed to clear failed transition [class=" + clazz +
", name=" + name + "].", pe);
}
throw rte;
}
} }
} }
@@ -104,13 +127,16 @@ public class TransitionRepository extends SimpleRepository
/** /**
* Note in the database that a particular transition has been applied. * Note in the database that a particular transition has been applied.
*
* @return true if the transition was noted, false if it could not be noted because another
* process noted it first.
*/ */
public void noteTransition (Class clazz, final String name) public boolean noteTransition (Class clazz, final String name)
throws PersistenceException throws PersistenceException
{ {
final String cname = clazz.getName(); final String cname = clazz.getName();
executeUpdate(new Operation<Void>() { return executeUpdate(new Operation<Boolean>() {
public Void invoke (Connection conn, DatabaseLiaison liaison) public Boolean invoke (Connection conn, DatabaseLiaison liaison)
throws SQLException, PersistenceException throws SQLException, PersistenceException
{ {
PreparedStatement stmt = null; PreparedStatement stmt = null;
@@ -122,11 +148,18 @@ public class TransitionRepository extends SimpleRepository
stmt.setString(1, cname); stmt.setString(1, cname);
stmt.setString(2, name); stmt.setString(2, name);
JDBCUtil.checkedUpdate(stmt, 1); JDBCUtil.checkedUpdate(stmt, 1);
return true;
} catch (SQLException sqe) {
if (liaison.isDuplicateRowException(sqe)) {
return false;
} else {
throw sqe;
}
} finally { } finally {
JDBCUtil.close(stmt); JDBCUtil.close(stmt);
} }
return null;
} }
}); });
} }