use of java.sql.Savepoint in project alfresco-repository by Alfresco.
the class AbstractNodeDAOImpl method updatePrimaryParentAssocsImpl.
protected int updatePrimaryParentAssocsImpl(ChildAssocEntity primaryParentAssoc, Node newParentNode, Node childNode, Long newChildNodeId, String childNodeName, Long oldParentNodeId, QName assocTypeQName, QName assocQName) {
Long newParentNodeId = newParentNode.getId();
Long childNodeId = childNode.getId();
Savepoint savepoint = controlDAO.createSavepoint("DuplicateChildNodeNameException");
// We use the child node's UUID if there is no cm:name
String childNodeNameToUse = childNodeName == null ? childNode.getUuid() : childNodeName;
try {
int updated = updatePrimaryParentAssocs(newChildNodeId, newParentNodeId, assocTypeQName, assocQName, childNodeNameToUse);
controlDAO.releaseSavepoint(savepoint);
// 'touch')
if (updated > 0 && primaryParentAssoc != null) {
Pair<Long, QName> oldTypeQnamePair = qnameDAO.getQName(primaryParentAssoc.getTypeQNameId());
if (oldTypeQnamePair != null) {
childByNameCache.remove(new ChildByNameKey(oldParentNodeId, oldTypeQnamePair.getSecond(), primaryParentAssoc.getChildNodeName()));
}
}
return updated;
} catch (Throwable e) {
controlDAO.rollbackToSavepoint(savepoint);
// DuplicateChildNodeNameException implements DoNotRetryException.
// There are some cases - FK violations, specifically - where we DO actually want to retry.
// Detecting this is done by looking for the related FK names, 'fk_alf_cass_*' in the error message
String lowerMsg = e.getMessage().toLowerCase();
if (lowerMsg.contains("fk_alf_cass_")) {
throw new ConcurrencyFailureException("FK violation updating primary parent association for " + childNodeId, e);
}
// We assume that this is from the child cm:name constraint violation
throw new DuplicateChildNodeNameException(newParentNode.getNodeRef(), assocTypeQName, childNodeName, e);
}
}
use of java.sql.Savepoint in project alfresco-repository by Alfresco.
the class EntityLookupCache method createOrGetByValue.
/**
* Attempt to create the entity and, failing that, look it up.<br/>
* This method takes the opposite approach to {@link #getOrCreateByValue(Object)}, which assumes the entity's
* existence: in this case the entity is assumed to NOT exist.
* The {@link EntityLookupCallbackDAO#createValue(Object)} and {@link EntityLookupCallbackDAO#findByValue(Object)}
* will be used if necessary.<br/>
* <p/>
* Use this method when the data involved is seldom reused.
*
* @param value The entity value (<tt>null</tt> is allowed)
* @param controlDAO an essential DAO required in order to ensure a transactionally-safe attempt at data creation
* @return Returns the key-value pair (new or existing and never <tt>null</tt>)
*/
public Pair<K, V> createOrGetByValue(V value, ControlDAO controlDAO) {
if (controlDAO == null) {
throw new IllegalArgumentException("The ControlDAO is required in order to perform a safe attempted insert.");
}
Savepoint savepoint = controlDAO.createSavepoint("EntityLookupCache.createOrGetByValue");
try {
Pair<K, V> entityPair = entityLookup.createValue(value);
controlDAO.releaseSavepoint(savepoint);
// Cache it
if (cache != null) {
cache.put(new CacheRegionKey(cacheRegion, entityPair.getFirst()), (entityPair.getSecond() == null ? VALUE_NULL : entityPair.getSecond()));
}
// It's been created and cached
return entityPair;
} catch (Exception e) {
controlDAO.rollbackToSavepoint(savepoint);
// Fall through to the usual way, which should find it if the failure cause was a duplicate key
return getOrCreateByValue(value);
}
}
use of java.sql.Savepoint in project sqlite-jna by gwenn.
the class Conn method setSavepoint.
@Override
public Savepoint setSavepoint(final String name) throws SQLException {
final Savepoint savepoint = new Savepoint() {
@Override
public int getSavepointId() throws SQLException {
throw new ConnException(c, "named savepoint", ErrCodes.WRAPPER_SPECIFIC);
}
@Override
public String getSavepointName() {
return name;
}
@Override
public String toString() {
return name;
}
};
org.sqlite.parser.ast.Savepoint sp = new org.sqlite.parser.ast.Savepoint(name);
getConn().fastExec(sp.toSql());
return savepoint;
}
use of java.sql.Savepoint in project sqlite-jna by gwenn.
the class SqliteConnectionTest method testSavepoint.
/*@Test
public void testAbort() throws Exception {
Sqlite3.ProgressCallbackBase delayCallback = new Sqlite3.ProgressCallbackBase() {
@Override
public int apply(Pointer<Void> context) {
try {
Thread.sleep(500);
} catch (InterruptedException e) {
}
return 0;
}
};
Sqlite3.sqlite3_progress_handler(((SqliteConnection)conn).getHandle(), 1, Pointer.pointerTo(delayCallback), null);
final List<Runnable> commandList = new ArrayList<>();
final Executor monitor = new Executor() {
@Override
public void execute(Runnable command) {
commandList.add(command);
}
};
Thread aborter = new Thread(new Runnable() {
@Override
public void run() {
try {
Thread.sleep(100);
conn.abort(monitor);
} catch (SQLException e) {
} catch (InterruptedException e) {
}
}
});
aborter.setDaemon(true);
aborter.start();
boolean reachedExecute = false;
try (Statement stmt = conn.createStatement()) {
reachedExecute = true;
stmt.executeUpdate("INSERT INTO test_table VALUES (2, 'test')");
fail("Statement was not aborted?");
}
catch (SQLException e) {
assertTrue(reachedExecute);
}
assertTrue(conn.isClosed());
assertEquals(1, commandList.size());
Thread waiter = new Thread(commandList.get(0));
waiter.setDaemon(true);
waiter.start();
waiter.join(100);
assertTrue(waiter.isAlive());
conn.close();
waiter.join(100);
assertFalse(waiter.isAlive());
}*/
@Test
public void testSavepoint() throws Exception {
/*
try {
conn.setSavepoint();
fail("Setting a savepoint should fail outside of autocommit");
}
catch (SQLException e) {
}
*/
conn.setAutoCommit(false);
try (Statement stmt = conn.createStatement()) {
stmt.executeUpdate("INSERT INTO test_table VALUES (2, 'test')");
Savepoint sp = conn.setSavepoint();
stmt.executeUpdate("INSERT INTO test_table VALUES (3, 'test')");
try {
sp.getSavepointName();
fail("Able to get savepoint name?");
} catch (SQLException e) {
}
sp.getSavepointId();
conn.rollback(sp);
conn.commit();
try {
conn.rollback(sp);
fail("Rollback should fail on an invalid savepoint");
} catch (SQLException e) {
}
try {
conn.releaseSavepoint(sp);
fail("Release should fail on an invalid savepoint");
} catch (SQLException e) {
}
try (ResultSet rs = stmt.executeQuery("SELECT * FROM test_table")) {
assertTrue(rs.next());
assertEquals(1, rs.getInt(1));
assertTrue(rs.next());
assertEquals(2, rs.getInt(1));
assertFalse(rs.next());
}
stmt.executeUpdate("INSERT INTO test_table VALUES (3, 'test')");
sp = conn.setSavepoint("test");
stmt.executeUpdate("INSERT INTO test_table VALUES (4, 'test')");
try {
sp.getSavepointId();
fail("Able to get savepoint id?");
} catch (SQLException e) {
}
assertEquals("test", sp.getSavepointName());
conn.rollback(sp);
conn.commit();
try (ResultSet rs = stmt.executeQuery("SELECT * FROM test_table")) {
assertTrue(rs.next());
assertEquals(1, rs.getInt(1));
assertTrue(rs.next());
assertEquals(2, rs.getInt(1));
assertTrue(rs.next());
assertEquals(3, rs.getInt(1));
assertFalse(rs.next());
}
stmt.executeUpdate("INSERT INTO test_table VALUES (4, 'test')");
sp = conn.setSavepoint("test");
stmt.executeUpdate("INSERT INTO test_table VALUES (5, 'test')");
conn.releaseSavepoint(sp);
conn.commit();
try (ResultSet rs = stmt.executeQuery("SELECT * FROM test_table")) {
assertTrue(rs.next());
assertEquals(1, rs.getInt(1));
assertTrue(rs.next());
assertEquals(2, rs.getInt(1));
assertTrue(rs.next());
assertEquals(3, rs.getInt(1));
assertTrue(rs.next());
assertEquals(4, rs.getInt(1));
assertTrue(rs.next());
assertEquals(5, rs.getInt(1));
assertFalse(rs.next());
}
}
}
use of java.sql.Savepoint in project sqlite-jna by gwenn.
the class SavepointTest method release.
@Test
public void release() throws SQLException {
ResultSet rs;
String countSql = "select count(*) from trans;";
stat1.executeUpdate("create table trans (c1);");
Savepoint outerSP = conn1.setSavepoint("outer_sp");
assertEquals(1, stat1.executeUpdate("insert into trans values (4);"));
// transaction not yet commited, conn1 can see, conn2 can not
rs = stat1.executeQuery(countSql);
assertTrue(rs.next());
assertEquals(1, rs.getInt(1));
rs.close();
rs = stat2.executeQuery(countSql);
assertTrue(rs.next());
assertEquals(0, rs.getInt(1));
rs.close();
Savepoint innerSP = conn1.setSavepoint("inner_sp");
assertEquals(1, stat1.executeUpdate("insert into trans values (5);"));
// transaction not yet commited, conn1 can see, conn2 can not
rs = stat1.executeQuery(countSql);
assertTrue(rs.next());
assertEquals(2, rs.getInt(1));
rs.close();
rs = stat2.executeQuery(countSql);
assertTrue(rs.next());
assertEquals(0, rs.getInt(1));
rs.close();
// releasing an inner savepoint, statements are still wrapped by the outer savepoint
conn1.releaseSavepoint(innerSP);
rs = stat2.executeQuery(countSql);
assertTrue(rs.next());
assertEquals(0, rs.getInt(1));
rs.close();
// releasing the outer savepoint is like a commit
conn1.releaseSavepoint(outerSP);
// all connects can see SP1 data
rs = stat2.executeQuery(countSql);
assertTrue(rs.next());
assertEquals(2, rs.getInt(1));
rs.close();
}
Aggregations