Search in sources :

Example 71 with Savepoint

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);
    }
}
Also used : DuplicateChildNodeNameException(org.alfresco.service.cmr.repository.DuplicateChildNodeNameException) QName(org.alfresco.service.namespace.QName) ConcurrencyFailureException(org.springframework.dao.ConcurrencyFailureException) Savepoint(java.sql.Savepoint) Savepoint(java.sql.Savepoint)

Example 72 with Savepoint

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);
    }
}
Also used : Savepoint(java.sql.Savepoint) ConcurrencyFailureException(org.springframework.dao.ConcurrencyFailureException)

Example 73 with Savepoint

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;
}
Also used : ConnException(org.sqlite.ConnException) Savepoint(java.sql.Savepoint)

Example 74 with 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());
        }
    }
}
Also used : SQLException(java.sql.SQLException) PreparedStatement(java.sql.PreparedStatement) Statement(java.sql.Statement) ResultSet(java.sql.ResultSet) Savepoint(java.sql.Savepoint) Test(org.junit.Test)

Example 75 with Savepoint

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();
}
Also used : ResultSet(java.sql.ResultSet) Savepoint(java.sql.Savepoint) Test(org.junit.Test)

Aggregations

Savepoint (java.sql.Savepoint)167 Statement (java.sql.Statement)61 Connection (java.sql.Connection)56 SQLException (java.sql.SQLException)55 PreparedStatement (java.sql.PreparedStatement)32 Test (org.junit.Test)31 ResultSet (java.sql.ResultSet)26 DatabaseMetaData (java.sql.DatabaseMetaData)13 UnitTest (nl.topicus.jdbc.test.category.UnitTest)13 TransactionStatus (org.springframework.transaction.TransactionStatus)12 TransactionCallbackWithoutResult (org.springframework.transaction.support.TransactionCallbackWithoutResult)12 TransactionTemplate (org.springframework.transaction.support.TransactionTemplate)12 ArrayList (java.util.ArrayList)11 Vector (java.util.Vector)11 Test (org.junit.jupiter.api.Test)10 ParameterizedTest (org.junit.jupiter.params.ParameterizedTest)10 SQLClientInfoException (java.sql.SQLClientInfoException)7 HashMap (java.util.HashMap)5 ConcurrencyFailureException (org.springframework.dao.ConcurrencyFailureException)5 SQLFeatureNotSupportedException (java.sql.SQLFeatureNotSupportedException)4