org.springframework.transaction.support.TransactionTemplate

Here are the examples of the java api org.springframework.transaction.support.TransactionTemplate taken from open source projects. By voting up you can indicate which examples are most useful and appropriate.

284 Examples 7

19 Source : EventHandlerService.java
with Apache License 2.0
from zhihuili

public void setTransactionTemplate(TransactionTemplate transactionTemplate) {
    this.transactionTemplate = transactionTemplate;
}

19 Source : SpringTransactionCommandService.java
with Apache License 2.0
from youseries

public <T> T executeCommand(final Command<T> command) {
    TransactionTemplate template = new TransactionTemplate(platformTransactionManager);
    template.setPropagationBehavior(springPropagationBehaviour);
    return template.execute(new TransactionCallback<T>() {

        public T doInTransaction(TransactionStatus status) {
            return command.execute(context);
        }
    });
}

19 Source : SpringTransactionCommandService.java
with Apache License 2.0
from youseries

public <T> T executeCommandInNewTransaction(final Command<T> command) {
    TransactionTemplate template = new TransactionTemplate(platformTransactionManager);
    template.setPropagationBehavior(newSpringPropagationBehaviour);
    return template.execute(new TransactionCallback<T>() {

        public T doInTransaction(TransactionStatus status) {
            return command.execute(context);
        }
    });
}

19 Source : PostgresDatabaseInitializer.java
with MIT License
from yoomoney-tech

/**
 * @author Oleg Kandaurov
 * @since 10.07.2017
 */
public clreplaced PostgresDatabaseInitializer {

    public static final String DEFAULT_TABLE_NAME = "queue_default";

    public static final String DEFAULT_TABLE_NAME_WO_INC = "queue_default_wo_inc";

    public static final String CUSTOM_TABLE_NAME = "queue_custom";

    public static final QueueTableSchema DEFAULT_SCHEMA = QueueTableSchema.builder().build();

    public static final QueueTableSchema CUSTOM_SCHEMA = QueueTableSchema.builder().withIdField("qid").withQueueNameField("qn").withPayloadField("pl").withCreatedAtField("ct").withNextProcessAtField("pt").withAttemptField("at").withReenqueueAttemptField("rat").withTotalAttemptField("tat").withExtFields(Collections.singletonList("trace")).build();

    private static final String PG_CUSTOM_TABLE_DDL = "CREATE TABLE %s (\n" + "  qid      BIGSERIAL PRIMARY KEY,\n" + "  qn    TEXT NOT NULL,\n" + "  pl    TEXT,\n" + "  ct    TIMESTAMP WITH TIME ZONE DEFAULT now(),\n" + "  pt    TIMESTAMP WITH TIME ZONE DEFAULT now(),\n" + "  at    INTEGER                  DEFAULT 0,\n" + "  rat   INTEGER                  DEFAULT 0,\n" + "  tat   INTEGER                  DEFAULT 0,\n" + "  trace TEXT \n" + ");" + "CREATE INDEX %s_name_time_desc_idx\n" + "  ON %s (qn, pt, qid DESC);\n" + "\n";

    private static final String PG_DEFAULT_TABLE_DDL = "CREATE TABLE %s (\n" + "  id                BIGSERIAL PRIMARY KEY,\n" + "  queue_name        TEXT NOT NULL,\n" + "  payload           TEXT,\n" + "  created_at        TIMESTAMP WITH TIME ZONE DEFAULT now(),\n" + "  next_process_at   TIMESTAMP WITH TIME ZONE DEFAULT now(),\n" + "  attempt           INTEGER                  DEFAULT 0,\n" + "  reenqueue_attempt INTEGER                  DEFAULT 0,\n" + "  total_attempt     INTEGER                  DEFAULT 0\n" + ");" + "CREATE INDEX %s_name_time_desc_idx\n" + "  ON %s (queue_name, next_process_at, id DESC);\n" + "\n";

    private static final String PG_DEFAULT_WO_INC_TABLE_DDL = "CREATE TABLE %s (\n" + "  id                BIGINT PRIMARY KEY,\n" + "  queue_name        TEXT NOT NULL,\n" + "  payload           TEXT,\n" + "  created_at        TIMESTAMP WITH TIME ZONE DEFAULT now(),\n" + "  next_process_at   TIMESTAMP WITH TIME ZONE DEFAULT now(),\n" + "  attempt           INTEGER                  DEFAULT 0,\n" + "  reenqueue_attempt INTEGER                  DEFAULT 0,\n" + "  total_attempt     INTEGER                  DEFAULT 0\n" + ");" + "CREATE INDEX %s_name_time_desc_idx\n" + "  ON %s (queue_name, next_process_at, id DESC);\n" + "\n";

    private static JdbcTemplate pgJdbcTemplate;

    private static TransactionTemplate pgTransactionTemplate;

    public static synchronized void initialize() {
        if (pgJdbcTemplate != null) {
            return;
        }
        String ryukImage = Optional.ofNullable(System.getProperty("testcontainers.ryuk.container.image")).orElse("quay.io/testcontainers/ryuk:0.2.3");
        TestcontainersConfiguration.getInstance().updateGlobalConfig("ryuk.container.image", ryukImage);
        String postgresImage = Optional.ofNullable(System.getProperty("testcontainers.postgresql.container.image")).orElse("postgres:9.5");
        PostgreSQLContainer<?> dbContainer = new PostgreSQLContainer<>(postgresImage);
        dbContainer.withEnv("POSTGRES_INITDB_ARGS", "--nosync");
        dbContainer.withCommand("postgres -c fsync=off -c full_page_writes=off -c synchronous_commit=off");
        dbContainer.start();
        PGSimpleDataSource dataSource = new PGSimpleDataSource();
        dataSource.setUrl(dbContainer.getJdbcUrl());
        dataSource.setPreplacedword(dbContainer.getPreplacedword());
        dataSource.setUser(dbContainer.getUsername());
        pgJdbcTemplate = new JdbcTemplate(dataSource);
        pgTransactionTemplate = new TransactionTemplate(new DataSourceTransactionManager(dataSource));
        pgTransactionTemplate.setIsolationLevel(TransactionDefinition.ISOLATION_READ_COMMITTED);
        pgTransactionTemplate.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED);
        executeDdl("CREATE SEQUENCE tasks_seq START 1");
        createTable(PG_DEFAULT_WO_INC_TABLE_DDL, DEFAULT_TABLE_NAME_WO_INC);
        createTable(PG_DEFAULT_TABLE_DDL, DEFAULT_TABLE_NAME);
        createTable(PG_CUSTOM_TABLE_DDL, CUSTOM_TABLE_NAME);
    }

    public static void createDefaultTable(String tableName) {
        createTable(PG_DEFAULT_TABLE_DDL, tableName);
    }

    private static void createTable(String ddlTemplate, String tableName) {
        initialize();
        executeDdl(String.format(ddlTemplate, tableName, tableName, tableName));
    }

    private static void executeDdl(String ddl) {
        initialize();
        getTransactionTemplate().execute(status -> {
            getJdbcTemplate().execute(ddl);
            return new Object();
        });
    }

    public static JdbcTemplate getJdbcTemplate() {
        initialize();
        return pgJdbcTemplate;
    }

    public static TransactionTemplate getTransactionTemplate() {
        initialize();
        return pgTransactionTemplate;
    }
}

19 Source : OracleDatabaseInitializer.java
with MIT License
from yoomoney-tech

/**
 * @author Oleg Kandaurov
 * @since 15.05.2020
 */
public clreplaced OracleDatabaseInitializer {

    static {
        // Oracle image has old timezone files so we make test independent of timezone
        TimeZone.setDefault(TimeZone.getTimeZone("UTC"));
    }

    public static final String DEFAULT_TABLE_NAME = "queue_default";

    public static final String CUSTOM_TABLE_NAME = "queue_custom";

    public static final QueueTableSchema DEFAULT_SCHEMA = QueueTableSchema.builder().build();

    public static final QueueTableSchema CUSTOM_SCHEMA = QueueTableSchema.builder().withIdField("qid").withQueueNameField("qn").withPayloadField("pl").withCreatedAtField("ct").withNextProcessAtField("pt").withAttemptField("att").withReenqueueAttemptField("rat").withTotalAttemptField("tat").withExtFields(Collections.singletonList("trace")).build();

    private static final String ORA_CUSTOM_TABLE_DDL = "CREATE TABLE %s (\n" + "  qid     NUMBER(38) NOT NULL PRIMARY KEY,\n" + "  qn     VARCHAR2(128) NOT NULL,\n" + "  pl     CLOB,\n" + "  ct     TIMESTAMP WITH LOCAL TIME ZONE DEFAULT CURRENT_TIMESTAMP,\n" + "  pt     TIMESTAMP WITH LOCAL TIME ZONE DEFAULT CURRENT_TIMESTAMP,\n" + "  att     NUMBER(38)                  DEFAULT 0,\n" + "  rat    NUMBER(38)                  DEFAULT 0,\n" + "  tat    NUMBER(38)                  DEFAULT 0,\n" + "  trace  VARCHAR2(512)                  DEFAULT 0\n" + ")";

    private static final String ORA_DEFAULT_TABLE_DDL = "CREATE TABLE %s (\n" + "  id                NUMBER(38) NOT NULL PRIMARY KEY,\n" + "  queue_name        VARCHAR2(128) NOT NULL,\n" + "  payload           CLOB,\n" + "  created_at        TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP,\n" + "  next_process_at   TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP,\n" + "  attempt           NUMBER(38)                  DEFAULT 0,\n" + "  reenqueue_attempt NUMBER(38)                  DEFAULT 0,\n" + "  total_attempt     NUMBER(38)                  DEFAULT 0\n" + ")";

    private static JdbcTemplate oraJdbcTemplate;

    private static TransactionTemplate oraTransactionTemplate;

    public static synchronized void initialize() {
        if (oraJdbcTemplate != null) {
            return;
        }
        String ryukImage = Optional.ofNullable(System.getProperty("testcontainers.ryuk.container.image")).orElse("quay.io/testcontainers/ryuk:0.2.3");
        TestcontainersConfiguration.getInstance().updateGlobalConfig("ryuk.container.image", ryukImage);
        String oracleImage = Optional.ofNullable(System.getProperty("testcontainers.oracle.container.image")).orElse("wnameless/oracle-xe-11g-r2");
        OracleContainer dbContainer = new OracleContainer(oracleImage);
        dbContainer.start();
        addUserAndSchema(dbContainer, "oracle_test");
        OracleDataSource dataSource = getDataSource(dbContainer, "oracle_test");
        oraJdbcTemplate = new JdbcTemplate(dataSource);
        oraTransactionTemplate = new TransactionTemplate(new DataSourceTransactionManager(dataSource));
        oraTransactionTemplate.setIsolationLevel(TransactionDefinition.ISOLATION_READ_COMMITTED);
        oraTransactionTemplate.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED);
        executeDdl("CREATE SEQUENCE tasks_seq START WITH 1");
        createTable(ORA_DEFAULT_TABLE_DDL, DEFAULT_TABLE_NAME);
        createTable(ORA_CUSTOM_TABLE_DDL, CUSTOM_TABLE_NAME);
    }

    private static OracleDataSource getDataSource(OracleContainer dbContainer, String userName) {
        OracleConnectionPoolDataSource dataSource;
        try {
            dataSource = new OracleConnectionPoolDataSource();
        } catch (SQLException e) {
            throw new IllegalStateException(e);
        }
        dataSource.setURL("jdbc:oracle:thin:" + userName + "/" + userName + "@localhost:" + dbContainer.getFirstMappedPort() + ":xe");
        return dataSource;
    }

    private static void addUserAndSchema(OracleContainer dbContainer, String userName) {
        Arrays.asList("CREATE USER " + userName + " IDENTIFIED BY " + userName + "", "ALTER USER " + userName + " QUOTA unlimited ON SYSTEM", "GRANT CREATE SESSION, CONNECT, RESOURCE, DBA TO " + userName, "GRANT ALL PRIVILEGES TO " + userName).forEach(s -> {
            try (Connection connection = dbContainer.createConnection("")) {
                try (PreparedStatement statement = connection.prepareStatement(s)) {
                    statement.executeUpdate();
                }
            } catch (Exception ex) {
                throw new IllegalStateException(ex);
            }
        });
    }

    private static void createTable(String ddlTemplate, String tableName) {
        initialize();
        executeDdl(String.format(ddlTemplate, tableName, tableName, tableName));
    }

    private static void executeDdl(String ddl) {
        initialize();
        getTransactionTemplate().execute(status -> {
            getJdbcTemplate().execute(ddl);
            return new Object();
        });
    }

    public static JdbcTemplate getJdbcTemplate() {
        initialize();
        return oraJdbcTemplate;
    }

    public static TransactionTemplate getTransactionTemplate() {
        initialize();
        return oraTransactionTemplate;
    }
}

19 Source : MssqlDatabaseInitializer.java
with MIT License
from yoomoney-tech

/**
 * @author Oleg Kandaurov
 * @since 10.07.2017
 */
public clreplaced MssqlDatabaseInitializer {

    public static final String DEFAULT_TABLE_NAME = "queue_default";

    public static final String DEFAULT_TABLE_NAME_WO_IDENT = "queue_default_wo_ident";

    public static final String CUSTOM_TABLE_NAME = "queue_custom";

    public static final QueueTableSchema DEFAULT_SCHEMA = QueueTableSchema.builder().build();

    public static final QueueTableSchema CUSTOM_SCHEMA = QueueTableSchema.builder().withIdField("qid").withQueueNameField("qn").withPayloadField("pl").withCreatedAtField("ct").withNextProcessAtField("pt").withAttemptField("at").withReenqueueAttemptField("rat").withTotalAttemptField("tat").withExtFields(Collections.singletonList("trace")).build();

    private static final String MS_CUSTOM_TABLE_DDL = "CREATE TABLE %s (\n" + "  qid    int idenreplacedy(1,1) not null,\n" + "  qn    varchar(127) not null,\n" + "  pl    text,\n" + "  ct    datetimeoffset not null default SYSDATETIMEOFFSET(),\n" + "  pt    datetimeoffset not null default SYSDATETIMEOFFSET(),\n" + "  at    integer not null         default 0,\n" + "  rat   integer not null         default 0,\n" + "  tat   integer not null         default 0,\n" + "  trace text \n" + "  primary key (qid)\n" + ");" + "CREATE INDEX %s_name_time_desc_idx\n" + "  ON %s (qn, pt, qid DESC);\n" + "\n";

    private static final String MS_DEFAULT_TABLE_DDL = "CREATE TABLE %s (\n" + "  id                int idenreplacedy(1,1) not null,\n" + "  queue_name        varchar(127) not null,\n" + "  payload           text,\n" + "  created_at        datetimeoffset not null default SYSDATETIMEOFFSET(),\n" + "  next_process_at   datetimeoffset not null default SYSDATETIMEOFFSET(),\n" + "  attempt           integer not null         default 0,\n" + "  reenqueue_attempt integer not null         default 0,\n" + "  total_attempt     integer not null         default 0,\n" + "  primary key (id)\n" + ");" + "CREATE INDEX %s_name_time_desc_idx\n" + "  ON %s (queue_name, next_process_at, id DESC);\n" + "\n";

    private static final String MS_DEFAULT_WO_IDENT_TABLE_DDL = "CREATE TABLE %s (\n" + "  id                int not null,\n" + "  queue_name        varchar(127) not null,\n" + "  payload           text,\n" + "  created_at        datetimeoffset not null default SYSDATETIMEOFFSET(),\n" + "  next_process_at   datetimeoffset not null default SYSDATETIMEOFFSET(),\n" + "  attempt           integer not null         default 0,\n" + "  reenqueue_attempt integer not null         default 0,\n" + "  total_attempt     integer not null         default 0,\n" + "  primary key (id)\n" + ");" + "CREATE INDEX %s_name_time_desc_idx\n" + "  ON %s (queue_name, next_process_at, id DESC);\n" + "\n";

    private static JdbcTemplate msJdbcTemplate;

    private static TransactionTemplate msTransactionTemplate;

    public static synchronized void initialize() {
        if (msJdbcTemplate != null) {
            return;
        }
        SQLServerDataSource dataSource;
        String ryukImage = Optional.ofNullable(System.getProperty("testcontainers.ryuk.container.image")).orElse("quay.io/testcontainers/ryuk:0.2.3");
        TestcontainersConfiguration.getInstance().updateGlobalConfig("ryuk.container.image", ryukImage);
        String mssqlImage = Optional.ofNullable(System.getProperty("testcontainers.mssql.container.image")).orElse("mcr.microsoft.com/mssql/server:2019-CU1-ubuntu-16.04");
        MSSQLServerContainer containerInstance = new MSSQLServerContainer<>(mssqlImage);
        containerInstance.start();
        URI uri = URI.create(containerInstance.getJdbcUrl().substring(5));
        dataSource = new SQLServerDataSource();
        dataSource.setServerName(uri.getHost());
        dataSource.setPortNumber(uri.getPort());
        dataSource.setUser(containerInstance.getUsername());
        dataSource.setPreplacedword(containerInstance.getPreplacedword());
        msJdbcTemplate = new JdbcTemplate(dataSource);
        msTransactionTemplate = new TransactionTemplate(new DataSourceTransactionManager(dataSource));
        msTransactionTemplate.setIsolationLevel(TransactionDefinition.ISOLATION_READ_COMMITTED);
        msTransactionTemplate.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED);
        executeDdl("CREATE SEQUENCE tasks_seq START WITH 1");
        createTable(MS_DEFAULT_TABLE_DDL, DEFAULT_TABLE_NAME);
        createTable(MS_DEFAULT_WO_IDENT_TABLE_DDL, DEFAULT_TABLE_NAME_WO_IDENT);
        createTable(MS_CUSTOM_TABLE_DDL, CUSTOM_TABLE_NAME);
    }

    private static void createTable(String ddlTemplate, String tableName) {
        initialize();
        executeDdl(String.format(ddlTemplate, tableName, tableName, tableName));
    }

    private static void executeDdl(String ddl) {
        initialize();
        getTransactionTemplate().execute(status -> {
            getJdbcTemplate().execute(ddl);
            return new Object();
        });
    }

    public static JdbcTemplate getJdbcTemplate() {
        initialize();
        return msJdbcTemplate;
    }

    public static TransactionTemplate getTransactionTemplate() {
        initialize();
        return msTransactionTemplate;
    }
}

19 Source : RestaurantJpaTest.java
with Apache License 2.0
from wuyichen24

/**
 * The integration test that verifies that an Restaurant can be persisted.
 *
 * @author  Wuyi Chen
 * @date    05/11/2020
 * @version 1.0
 * @since   1.0
 */
@RunWith(SpringRunner.clreplaced)
@SpringBootTest(clreplacedes = OrderJpaTestConfiguration.clreplaced)
public clreplaced RestaurantJpaTest {

    @Autowired
    private RestaurantRepository restaurantRepository;

    @Autowired
    private TransactionTemplate transactionTemplate;

    @Test
    public void shouldSaveRestaurant() {
        transactionTemplate.execute((ts) -> {
            Restaurant restaurant = new Restaurant(AJANTA_ID, AJANTA_RESTAURANT_NAME, AJANTA_RESTAURANT_MENU_ITEMS);
            restaurantRepository.save(restaurant);
            return null;
        });
        transactionTemplate.execute((ts) -> {
            Restaurant restaurant = new Restaurant(AJANTA_ID, AJANTA_RESTAURANT_NAME, AJANTA_RESTAURANT_MENU_ITEMS);
            restaurantRepository.save(restaurant);
            return null;
        });
    }
}

19 Source : TransactionAwareCacheDecoratorTests.java
with Apache License 2.0
from SourceHot

/**
 * @author Stephane Nicoll
 * @author Juergen Hoeller
 */
public clreplaced TransactionAwareCacheDecoratorTests {

    private final TransactionTemplate txTemplate = new TransactionTemplate(new CallCountingTransactionManager());

    @Test
    public void createWithNullTarget() {
        replacedertThatIllegalArgumentException().isThrownBy(() -> new TransactionAwareCacheDecorator(null));
    }

    @Test
    public void getTargetCache() {
        Cache target = new ConcurrentMapCache("testCache");
        TransactionAwareCacheDecorator cache = new TransactionAwareCacheDecorator(target);
        replacedertThat(cache.getTargetCache()).isSameAs(target);
    }

    @Test
    public void regularOperationsOnTarget() {
        Cache target = new ConcurrentMapCache("testCache");
        Cache cache = new TransactionAwareCacheDecorator(target);
        replacedertThat(cache.getName()).isEqualTo(target.getName());
        replacedertThat(cache.getNativeCache()).isEqualTo(target.getNativeCache());
        Object key = new Object();
        target.put(key, "123");
        replacedertThat(cache.get(key).get()).isEqualTo("123");
        replacedertThat(cache.get(key, String.clreplaced)).isEqualTo("123");
        cache.clear();
        replacedertThat(target.get(key)).isNull();
    }

    @Test
    public void putNonTransactional() {
        Cache target = new ConcurrentMapCache("testCache");
        Cache cache = new TransactionAwareCacheDecorator(target);
        Object key = new Object();
        cache.put(key, "123");
        replacedertThat(target.get(key, String.clreplaced)).isEqualTo("123");
    }

    @Test
    public void putTransactional() {
        Cache target = new ConcurrentMapCache("testCache");
        Cache cache = new TransactionAwareCacheDecorator(target);
        Object key = new Object();
        txTemplate.executeWithoutResult(s -> {
            cache.put(key, "123");
            replacedertThat(target.get(key)).isNull();
        });
        replacedertThat(target.get(key, String.clreplaced)).isEqualTo("123");
    }

    @Test
    public void putIfAbsentNonTransactional() {
        Cache target = new ConcurrentMapCache("testCache");
        Cache cache = new TransactionAwareCacheDecorator(target);
        Object key = new Object();
        replacedertThat(cache.putIfAbsent(key, "123")).isNull();
        replacedertThat(target.get(key, String.clreplaced)).isEqualTo("123");
        replacedertThat(cache.putIfAbsent(key, "456").get()).isEqualTo("123");
        // unchanged
        replacedertThat(target.get(key, String.clreplaced)).isEqualTo("123");
    }

    @Test
    public void putIfAbsentTransactional() {
        // no transactional support for putIfAbsent
        Cache target = new ConcurrentMapCache("testCache");
        Cache cache = new TransactionAwareCacheDecorator(target);
        Object key = new Object();
        txTemplate.executeWithoutResult(s -> {
            replacedertThat(cache.putIfAbsent(key, "123")).isNull();
            replacedertThat(target.get(key, String.clreplaced)).isEqualTo("123");
            replacedertThat(cache.putIfAbsent(key, "456").get()).isEqualTo("123");
            // unchanged
            replacedertThat(target.get(key, String.clreplaced)).isEqualTo("123");
        });
        replacedertThat(target.get(key, String.clreplaced)).isEqualTo("123");
    }

    @Test
    public void evictNonTransactional() {
        Cache target = new ConcurrentMapCache("testCache");
        Cache cache = new TransactionAwareCacheDecorator(target);
        Object key = new Object();
        cache.put(key, "123");
        cache.evict(key);
        replacedertThat(target.get(key)).isNull();
    }

    @Test
    public void evictTransactional() {
        Cache target = new ConcurrentMapCache("testCache");
        Cache cache = new TransactionAwareCacheDecorator(target);
        Object key = new Object();
        cache.put(key, "123");
        txTemplate.executeWithoutResult(s -> {
            cache.evict(key);
            replacedertThat(target.get(key, String.clreplaced)).isEqualTo("123");
        });
        replacedertThat(target.get(key)).isNull();
    }

    @Test
    public void evictIfPresentNonTransactional() {
        Cache target = new ConcurrentMapCache("testCache");
        Cache cache = new TransactionAwareCacheDecorator(target);
        Object key = new Object();
        cache.put(key, "123");
        cache.evictIfPresent(key);
        replacedertThat(target.get(key)).isNull();
    }

    @Test
    public void evictIfPresentTransactional() {
        // no transactional support for evictIfPresent
        Cache target = new ConcurrentMapCache("testCache");
        Cache cache = new TransactionAwareCacheDecorator(target);
        Object key = new Object();
        cache.put(key, "123");
        txTemplate.executeWithoutResult(s -> {
            cache.evictIfPresent(key);
            replacedertThat(target.get(key)).isNull();
        });
        replacedertThat(target.get(key)).isNull();
    }

    @Test
    public void clearNonTransactional() {
        Cache target = new ConcurrentMapCache("testCache");
        Cache cache = new TransactionAwareCacheDecorator(target);
        Object key = new Object();
        cache.put(key, "123");
        cache.clear();
        replacedertThat(target.get(key)).isNull();
    }

    @Test
    public void clearTransactional() {
        Cache target = new ConcurrentMapCache("testCache");
        Cache cache = new TransactionAwareCacheDecorator(target);
        Object key = new Object();
        cache.put(key, "123");
        txTemplate.executeWithoutResult(s -> {
            cache.clear();
            replacedertThat(target.get(key, String.clreplaced)).isEqualTo("123");
        });
        replacedertThat(target.get(key)).isNull();
    }

    @Test
    public void invalidateNonTransactional() {
        Cache target = new ConcurrentMapCache("testCache");
        Cache cache = new TransactionAwareCacheDecorator(target);
        Object key = new Object();
        cache.put(key, "123");
        cache.invalidate();
        replacedertThat(target.get(key)).isNull();
    }

    @Test
    public void invalidateTransactional() {
        // no transactional support for invalidate
        Cache target = new ConcurrentMapCache("testCache");
        Cache cache = new TransactionAwareCacheDecorator(target);
        Object key = new Object();
        cache.put(key, "123");
        txTemplate.executeWithoutResult(s -> {
            cache.invalidate();
            replacedertThat(target.get(key)).isNull();
        });
        replacedertThat(target.get(key)).isNull();
    }
}

19 Source : JCacheEhCacheAnnotationTests.java
with Apache License 2.0
from SourceHot

/**
 * @author Stephane Nicoll
 * @author Juergen Hoeller
 */
public clreplaced JCacheEhCacheAnnotationTests extends AbstractCacheAnnotationTests {

    private final TransactionTemplate txTemplate = new TransactionTemplate(new CallCountingTransactionManager());

    private CacheManager jCacheManager;

    @Override
    protected ConfigurableApplicationContext getApplicationContext() {
        AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
        context.getBeanFactory().registerSingleton("cachingProvider", getCachingProvider());
        context.register(EnableCachingConfig.clreplaced);
        context.refresh();
        jCacheManager = context.getBean("jCacheManager", CacheManager.clreplaced);
        return context;
    }

    protected CachingProvider getCachingProvider() {
        return Caching.getCachingProvider("org.ehcache.jcache.JCacheCachingProvider");
    }

    @AfterEach
    public void shutdown() {
        if (jCacheManager != null) {
            jCacheManager.close();
        }
    }

    @Override
    @Test
    @Disabled("Multi cache manager support to be added")
    public void testCustomCacheManager() {
    }

    @Test
    public void testEvictWithTransaction() {
        txTemplate.executeWithoutResult(s -> testEvict(this.cs, false));
    }

    @Test
    public void testEvictEarlyWithTransaction() {
        txTemplate.executeWithoutResult(s -> testEvictEarly(this.cs));
    }

    @Test
    public void testEvictAllWithTransaction() {
        txTemplate.executeWithoutResult(s -> testEvictAll(this.cs, false));
    }

    @Test
    public void testEvictAllEarlyWithTransaction() {
        txTemplate.executeWithoutResult(s -> testEvictAllEarly(this.cs));
    }

    @Configuration
    @EnableCaching
    static clreplaced EnableCachingConfig extends CachingConfigurerSupport {

        @Autowired
        CachingProvider cachingProvider;

        @Override
        @Bean
        public org.springframework.cache.CacheManager cacheManager() {
            JCacheCacheManager cm = new JCacheCacheManager(jCacheManager());
            cm.setTransactionAware(true);
            return cm;
        }

        @Bean
        public CacheManager jCacheManager() {
            CacheManager cacheManager = this.cachingProvider.getCacheManager();
            MutableConfiguration<Object, Object> mutableConfiguration = new MutableConfiguration<>();
            // otherwise value has to be Serializable
            mutableConfiguration.setStoreByValue(false);
            cacheManager.createCache("testCache", mutableConfiguration);
            cacheManager.createCache("primary", mutableConfiguration);
            cacheManager.createCache("secondary", mutableConfiguration);
            return cacheManager;
        }

        @Bean
        public CacheableService<?> service() {
            return new DefaultCacheableService();
        }

        @Bean
        public CacheableService<?> clreplacedService() {
            return new AnnotatedClreplacedCacheableService();
        }

        @Override
        @Bean
        public KeyGenerator keyGenerator() {
            return new SimpleKeyGenerator();
        }

        @Bean
        public KeyGenerator customKeyGenerator() {
            return new SomeCustomKeyGenerator();
        }
    }
}

19 Source : SecondTccActionImpl.java
with Apache License 2.0
from seata

/**
 * 加钱参与者实现
 *
 * @author zhangsen
 */
public clreplaced SecondTccActionImpl implements SecondTccAction {

    /**
     * 加钱账户 DAP
     */
    private AccountDAO toAccountDAO;

    private TransactionTemplate toDsTransactionTemplate;

    /**
     * 一阶段准备,转入资金 准备
     * @param businessActionContext
     * @param accountNo
     * @param amount
     * @return
     */
    @Override
    public boolean prepareAdd(final BusinessActionContext businessActionContext, final String accountNo, final double amount) {
        // 分布式事务ID
        final String xid = businessActionContext.getXid();
        return toDsTransactionTemplate.execute(new TransactionCallback<Boolean>() {

            @Override
            public Boolean doInTransaction(TransactionStatus status) {
                try {
                    // 校验账户
                    Account account = toAccountDAO.getAccountForUpdate(accountNo);
                    if (account == null) {
                        System.out.println("prepareAdd: 账户[" + accountNo + "]不存在, txId:" + businessActionContext.getXid());
                        return false;
                    }
                    // 待转入资金作为 不可用金额
                    double freezedAmount = account.getFreezedAmount() + amount;
                    account.setFreezedAmount(freezedAmount);
                    toAccountDAO.updateFreezedAmount(account);
                    System.out.println(String.format("prepareAdd account[%s] amount[%f], dtx transaction id: %s.", accountNo, amount, xid));
                    return true;
                } catch (Throwable t) {
                    t.printStackTrace();
                    status.setRollbackOnly();
                    return false;
                }
            }
        });
    }

    /**
     * 二阶段提交
     * @param businessActionContext
     * @return
     */
    @Override
    public boolean commit(BusinessActionContext businessActionContext) {
        // 分布式事务ID
        final String xid = businessActionContext.getXid();
        // 账户ID
        final String accountNo = String.valueOf(businessActionContext.getActionContext("accountNo"));
        // 转出金额
        final double amount = Double.valueOf(String.valueOf(businessActionContext.getActionContext("amount")));
        return toDsTransactionTemplate.execute(new TransactionCallback<Boolean>() {

            @Override
            public Boolean doInTransaction(TransactionStatus status) {
                try {
                    Account account = toAccountDAO.getAccountForUpdate(accountNo);
                    // 加钱
                    double newAmount = account.getAmount() + amount;
                    account.setAmount(newAmount);
                    // 冻结金额 清除
                    account.setFreezedAmount(account.getFreezedAmount() - amount);
                    toAccountDAO.updateAmount(account);
                    System.out.println(String.format("add account[%s] amount[%f], dtx transaction id: %s.", accountNo, amount, xid));
                    return true;
                } catch (Throwable t) {
                    t.printStackTrace();
                    status.setRollbackOnly();
                    return false;
                }
            }
        });
    }

    /**
     * 二阶段回滚
     * @param businessActionContext
     * @return
     */
    @Override
    public boolean rollback(BusinessActionContext businessActionContext) {
        // 分布式事务ID
        final String xid = businessActionContext.getXid();
        // 账户ID
        final String accountNo = String.valueOf(businessActionContext.getActionContext("accountNo"));
        // 转出金额
        final double amount = Double.valueOf(String.valueOf(businessActionContext.getActionContext("amount")));
        return toDsTransactionTemplate.execute(new TransactionCallback<Boolean>() {

            @Override
            public Boolean doInTransaction(TransactionStatus status) {
                try {
                    Account account = toAccountDAO.getAccountForUpdate(accountNo);
                    if (account == null) {
                        // 账户不存在, 无需回滚动作
                        return true;
                    }
                    // 冻结金额 清除
                    account.setFreezedAmount(account.getFreezedAmount() - amount);
                    toAccountDAO.updateFreezedAmount(account);
                    System.out.println(String.format("Undo prepareAdd account[%s] amount[%f], dtx transaction id: %s.", accountNo, amount, xid));
                    return true;
                } catch (Throwable t) {
                    t.printStackTrace();
                    status.setRollbackOnly();
                    return false;
                }
            }
        });
    }

    public void setToAccountDAO(AccountDAO toAccountDAO) {
        this.toAccountDAO = toAccountDAO;
    }

    public void setToDsTransactionTemplate(TransactionTemplate toDsTransactionTemplate) {
        this.toDsTransactionTemplate = toDsTransactionTemplate;
    }
}

19 Source : SecondTccActionImpl.java
with Apache License 2.0
from seata

public void setToDsTransactionTemplate(TransactionTemplate toDsTransactionTemplate) {
    this.toDsTransactionTemplate = toDsTransactionTemplate;
}

19 Source : FirstTccActionImpl.java
with Apache License 2.0
from seata

/**
 * 扣钱参与者实现
 *
 * @author zhangsen
 */
public clreplaced FirstTccActionImpl implements FirstTccAction {

    /**
     * 扣钱账户 DAO
     */
    private AccountDAO fromAccountDAO;

    /**
     * 扣钱数据源事务模板
     */
    private TransactionTemplate fromDsTransactionTemplate;

    /**
     * 一阶段准备,冻结 转账资金
     * @param businessActionContext
     * @param accountNo
     * @param amount
     * @return
     */
    @Override
    public boolean prepareMinus(BusinessActionContext businessActionContext, final String accountNo, final double amount) {
        // 分布式事务ID
        final String xid = businessActionContext.getXid();
        return fromDsTransactionTemplate.execute(new TransactionCallback<Boolean>() {

            @Override
            public Boolean doInTransaction(TransactionStatus status) {
                try {
                    // 校验账户余额
                    Account account = fromAccountDAO.getAccountForUpdate(accountNo);
                    if (account == null) {
                        throw new RuntimeException("账户不存在");
                    }
                    if (account.getAmount() - amount < 0) {
                        throw new RuntimeException("余额不足");
                    }
                    // 冻结转账金额
                    double freezedAmount = account.getFreezedAmount() + amount;
                    account.setFreezedAmount(freezedAmount);
                    fromAccountDAO.updateFreezedAmount(account);
                    System.out.println(String.format("prepareMinus account[%s] amount[%f], dtx transaction id: %s.", accountNo, amount, xid));
                    return true;
                } catch (Throwable t) {
                    t.printStackTrace();
                    status.setRollbackOnly();
                    return false;
                }
            }
        });
    }

    /**
     * 二阶段提交
     * @param businessActionContext
     * @return
     */
    @Override
    public boolean commit(BusinessActionContext businessActionContext) {
        // 分布式事务ID
        final String xid = businessActionContext.getXid();
        // 账户ID
        final String accountNo = String.valueOf(businessActionContext.getActionContext("accountNo"));
        // 转出金额
        final double amount = Double.valueOf(String.valueOf(businessActionContext.getActionContext("amount")));
        return fromDsTransactionTemplate.execute(new TransactionCallback<Boolean>() {

            @Override
            public Boolean doInTransaction(TransactionStatus status) {
                try {
                    Account account = fromAccountDAO.getAccountForUpdate(accountNo);
                    // 扣除账户余额
                    double newAmount = account.getAmount() - amount;
                    if (newAmount < 0) {
                        throw new RuntimeException("余额不足");
                    }
                    account.setAmount(newAmount);
                    // 释放账户 冻结金额
                    account.setFreezedAmount(account.getFreezedAmount() - amount);
                    fromAccountDAO.updateAmount(account);
                    System.out.println(String.format("minus account[%s] amount[%f], dtx transaction id: %s.", accountNo, amount, xid));
                    return true;
                } catch (Throwable t) {
                    t.printStackTrace();
                    status.setRollbackOnly();
                    return false;
                }
            }
        });
    }

    /**
     * 二阶段回滚
     * @param businessActionContext
     * @return
     */
    @Override
    public boolean rollback(BusinessActionContext businessActionContext) {
        // 分布式事务ID
        final String xid = businessActionContext.getXid();
        // 账户ID
        final String accountNo = String.valueOf(businessActionContext.getActionContext("accountNo"));
        // 转出金额
        final double amount = Double.valueOf(String.valueOf(businessActionContext.getActionContext("amount")));
        return fromDsTransactionTemplate.execute(new TransactionCallback<Boolean>() {

            @Override
            public Boolean doInTransaction(TransactionStatus status) {
                try {
                    Account account = fromAccountDAO.getAccountForUpdate(accountNo);
                    if (account == null) {
                        // 账户不存在,回滚什么都不做
                        return true;
                    }
                    // 释放冻结金额
                    account.setFreezedAmount(account.getFreezedAmount() - amount);
                    fromAccountDAO.updateFreezedAmount(account);
                    System.out.println(String.format("Undo prepareMinus account[%s] amount[%f], dtx transaction id: %s.", accountNo, amount, xid));
                    return true;
                } catch (Throwable t) {
                    t.printStackTrace();
                    status.setRollbackOnly();
                    return false;
                }
            }
        });
    }

    public void setFromAccountDAO(AccountDAO fromAccountDAO) {
        this.fromAccountDAO = fromAccountDAO;
    }

    public void setFromDsTransactionTemplate(TransactionTemplate fromDsTransactionTemplate) {
        this.fromDsTransactionTemplate = fromDsTransactionTemplate;
    }
}

19 Source : FirstTccActionImpl.java
with Apache License 2.0
from seata

public void setFromDsTransactionTemplate(TransactionTemplate fromDsTransactionTemplate) {
    this.fromDsTransactionTemplate = fromDsTransactionTemplate;
}

19 Source : EmployeeController.java
with MIT License
from ralscha

@RestController
public clreplaced EmployeeController {

    private final EmployeeDao employeeDao;

    private final DSLContext dsl;

    private final TransactionTemplate transactionTemplate;

    public EmployeeController(DSLContext dsl, Configuration jooqConfiguration, TransactionTemplate transactionTemplate) {
        this.employeeDao = new EmployeeDao(jooqConfiguration);
        this.dsl = dsl;
        this.transactionTemplate = transactionTemplate;
    }

    @GetMapping("/listEmployees")
    public List<Employee> employees() {
        return this.employeeDao.findAll();
    }

    @PostMapping("/deleteEmployee")
    public void delete(@RequestParam("id") int id) {
        this.employeeDao.deleteById(id);
    }

    @PostMapping("/newEmployee")
    public Employee newEmployee(@RequestBody Employee newEmployee) {
        this.employeeDao.insert(newEmployee);
        System.out.println(newEmployee.getId());
        return newEmployee;
    }

    @PostMapping("/updateEmployee")
    public Employee updateEmployee(@RequestBody Employee newEmployee) {
        this.employeeDao.update(newEmployee);
        return newEmployee;
    }

    @GetMapping("/findEmployees/{name}")
    public Integer[] findEmployees(@PathVariable("name") String name) {
        return this.dsl.select(EMPLOYEE.ID).from(EMPLOYEE).where(EMPLOYEE.FIRST_NAME.contains(name).or(EMPLOYEE.FIRST_NAME.contains(name))).fetchArray(EMPLOYEE.ID);
    }

    @GetMapping("/countEmployees")
    public int count() {
        return this.dsl.fetchCount(EMPLOYEE);
    }

    @GetMapping("/insertMultiple1")
    @Transactional
    public void insertMultiple1() {
        Employee e1 = new Employee();
        e1.setFirstName("1");
        e1.setLastName("1");
        e1.setUserName("1");
        e1.setBirthDate(LocalDate.now());
        e1.setGender("M");
        e1.setHireDate(LocalDate.now());
        this.employeeDao.insert(e1);
        if (true) {
            throw new NullPointerException();
        }
        Employee e2 = new Employee();
        e2.setFirstName("2");
        e2.setLastName("2");
        e2.setUserName("2");
        e2.setBirthDate(LocalDate.now());
        e2.setGender("M");
        e2.setHireDate(LocalDate.now());
        this.employeeDao.insert(e2);
    }

    @GetMapping("/insertMultiple2")
    public void insertMultiple2() {
        this.transactionTemplate.execute(txStatus -> {
            Employee e1 = new Employee();
            e1.setFirstName("1");
            e1.setLastName("1");
            e1.setUserName("1");
            e1.setBirthDate(LocalDate.now());
            e1.setGender("M");
            e1.setHireDate(LocalDate.now());
            this.employeeDao.insert(e1);
            if (true) {
                throw new NullPointerException();
            }
            Employee e2 = new Employee();
            e2.setFirstName("2");
            e2.setLastName("2");
            e2.setUserName("2");
            e2.setBirthDate(LocalDate.now());
            e2.setGender("M");
            e2.setHireDate(LocalDate.now());
            this.employeeDao.insert(e2);
            return null;
        });
    }

    @GetMapping("/insertMultiple3")
    public void insertMultiple3() {
        this.dsl.transaction(txConf -> {
            EmployeeDao txEd = new EmployeeDao(txConf);
            Employee e1 = new Employee();
            e1.setFirstName("1");
            e1.setLastName("1");
            e1.setUserName("1");
            e1.setBirthDate(LocalDate.now());
            e1.setGender("M");
            e1.setHireDate(LocalDate.now());
            txEd.insert(e1);
            int count = DSL.using(txConf).fetchCount(EMPLOYEE);
            System.out.println(count);
            if (true) {
                throw new NullPointerException();
            }
            Employee e2 = new Employee();
            e2.setFirstName("2");
            e2.setLastName("2");
            e2.setUserName("2");
            e2.setBirthDate(LocalDate.now());
            e2.setGender("M");
            e2.setHireDate(LocalDate.now());
            txEd.insert(e2);
        });
    }
}

19 Source : DatabaseMasterSelectorImpl.java
with Apache License 2.0
from QNJR-GROUP

private void initInstanceIdAndRecord() {
    TransactionTemplate transTemplate = new TransactionTemplate(transManager);
    transTemplate.execute(new TransactionCallback<Object>() {

        @Override
        public Object doInTransaction(TransactionStatus status) {
            Integer maxInstanceId = jdbcTemplate.queryForObject(GET_MAX_INSTANCE_ID, Integer.clreplaced, new Object[] { applicationName });
            instanceId = maxInstanceId + 1;
            int update = jdbcTemplate.update(INSERT_INSTANCE_CONTROL_LINE, applicationName, instanceId, instanceName);
            if (update != 1) {
                throw new RuntimeException("insert instance record failed! instanceId:" + maxInstanceId + " updated:" + update);
            }
            return null;
        }
    });
}

19 Source : TransactionTemplateFactory.java
with Apache License 2.0
from penggle

public TransactionTemplate createTransactionTemplate(int propagation, boolean readOnly) {
    TransactionTemplate transactionTemplate = new TransactionTemplate(platformTransactionManager);
    transactionTemplate.setPropagationBehavior(propagation);
    transactionTemplate.setReadOnly(readOnly);
    return transactionTemplate;
}

19 Source : AccountServiceImpl.java
with MIT License
from PacktPublishing

/**
 * @author Dinesh.Rajput
 */
@Service
public clreplaced AccountServiceImpl implements AccountService {

    // single TransactionTemplate shared amongst all methods in this instance
    private final TransactionTemplate transactionTemplate;

    @Autowired
    @Qualifier("hibernateAccountRepository")
    AccountRepository accountRepository;

    // use constructor-injection to supply the PlatformTransactionManager
    public AccountServiceImpl(PlatformTransactionManager transactionManager) {
        this.transactionTemplate = new TransactionTemplate(transactionManager);
    }

    @Override
    public Double cheeckAccountBalance(Account account) {
        return transactionTemplate.execute(new TransactionCallback<Double>() {

            // the code in this method executes in a transactional context
            public Double doInTransaction(TransactionStatus status) {
                return accountRepository.checkAccountBalance(account);
            }
        });
    }
}

19 Source : AbstractDbTest.java
with Apache License 2.0
from OpenWiseSolutions

/**
 * Creates and saves new messages.
 *
 * @param messageCount How many messages will be created
 * @param sourceSystem the source system
 * @param service the service
 * @param operationName the operation name
 * @param payload the payload
 * @return messages
 */
protected Message[] createAndSaveMessages(final int messageCount, final ExternalSystemExtEnum sourceSystem, final ServiceExtEnum service, final String operationName, final String payload) {
    TransactionTemplate tx = new TransactionTemplate(transactionManager);
    return tx.execute(new TransactionCallback<Message[]>() {

        @Override
        public Message[] doInTransaction(TransactionStatus status) {
            Message[] messages = new Message[messageCount];
            for (int i = 0; i < messages.length; i++) {
                messages[i] = createMessage(sourceSystem, service, operationName, payload);
                messages[i].setMsgTimestamp(Instant.now().plusSeconds(i * 5L));
                em.persist(messages[i]);
            }
            em.flush();
            return messages;
        }
    });
}

19 Source : AbstractDbTest.java
with Apache License 2.0
from OpenWiseSolutions

/**
 * Creates and saves new messages.
 *
 * @param messageCount How many messages will be created
 * @param messageCallback Callback handler that can adjust {@link Message}
 * @return messages
 */
protected Message[] createAndSaveMessages(final int messageCount, final MessageCallback messageCallback) {
    TransactionTemplate tx = new TransactionTemplate(transactionManager);
    return tx.execute(new TransactionCallback<Message[]>() {

        @Override
        public Message[] doInTransaction(TransactionStatus status) {
            Message[] messages = new Message[messageCount];
            for (int i = 0; i < messages.length; i++) {
                messages[i] = createMessage(ExternalSystemTestEnum.CRM, ServiceTestEnum.CUSTOMER, "testOperation", "test payload");
                try {
                    messageCallback.beforeInsert(messages[i], i + 1);
                } catch (Exception exc) {
                    throw new RuntimeException(exc);
                }
                em.persist(messages[i]);
            }
            em.flush();
            return messages;
        }
    });
}

19 Source : RepairExternalCallDbImplTest.java
with Apache License 2.0
from OpenWiseSolutions

private ExternalCall[] createAndSaveExternalCalls(final int quanreplacedy) {
    TransactionTemplate tx = new TransactionTemplate(transactionManager);
    return tx.execute(new TransactionCallback<ExternalCall[]>() {

        @Override
        public ExternalCall[] doInTransaction(TransactionStatus status) {
            ExternalCall[] extCalls = new ExternalCall[quanreplacedy];
            for (int i = 0; i < extCalls.length; i++) {
                Message message = createMessage(ExternalSystemTestEnum.CRM, ServiceTestEnum.CUSTOMER, "someOperation", "some payload");
                extCalls[i] = ExternalCall.createProcessingCall("direct:someOperation", UUID.randomUUID().toString(), message);
                extCalls[i].setLastUpdateTimestamp(Instant.now().minus(1, ChronoUnit.HOURS));
                em.persist(message);
                em.persist(extCalls[i]);
            }
            em.flush();
            return extCalls;
        }
    });
}

19 Source : HistoryManager.java
with Apache License 2.0
from OpenPlaceReviews

@Service
public clreplaced HistoryManager {

    public static final String ASC_SORT = "ASC";

    public static final String DESC_SORT = "DESC";

    public static final String HISTORY_BY_USER = "user";

    public static final String HISTORY_BY_OBJECT = "object";

    public static final String HISTORY_BY_TYPE = "type";

    public static final String HISTORY_ALL = "all";

    public static final String HISTORY_BY_OPERATION_HASH = "operation";

    private static final SimpleDateFormat DATE_FORMAT = new SimpleDateFormat(OpObject.DATE_FORMAT);

    @Autowired
    private DBSchemaManager dbSchema;

    @Autowired
    private BlocksManager blocksManager;

    @Autowired
    private JdbcTemplate jdbcTemplate;

    @Autowired
    private TransactionTemplate txTemplate;

    @Autowired
    private JsonFormatter formatter;

    @Autowired
    private SettingsManager settingsManager;

    public boolean isRunning() {
        return settingsManager.OPENDB_STORE_HISTORY.get();
    }

    public void saveHistoryForBlockOperations(OpBlock opBlock, DeletedObjectCtx hctx) {
        if (!isRunning()) {
            return;
        }
        txTemplate.execute(new TransactionCallback<Void>() {

            @Override
            public Void doInTransaction(TransactionStatus status) {
                Date date = new Date(opBlock.getDate(OpBlock.F_DATE));
                for (OpOperation o : opBlock.getOperations()) {
                    List<Object[]> allBatches = generateHistoryObjBatch(opBlock, o, date, hctx);
                    dbSchema.insertObjIntoHistoryTableBatch(allBatches, OP_OBJ_HISTORY_TABLE, jdbcTemplate);
                }
                return null;
            }
        });
    }

    public void retrieveHistory(HistoryObjectRequest historyObjectRequest) {
        String sql;
        switch(historyObjectRequest.historyType) {
            case HISTORY_BY_USER:
                {
                    StringBuilder userString = getUserSqlRequestString(historyObjectRequest);
                    sql = "SELECT usr_1, login_1, usr_2, login_2, p1, p2, p3, p4, p5, time, obj, type, status, ophash FROM " + OP_OBJ_HISTORY_TABLE + " WHERE " + userString + " ORDER BY sorder " + historyObjectRequest.sort + " LIMIT " + historyObjectRequest.limit;
                    loadHistory(sql, historyObjectRequest);
                    break;
                }
            case HISTORY_BY_OBJECT:
                {
                    String objType = null;
                    if (historyObjectRequest.key.size() > 1) {
                        objType = historyObjectRequest.key.get(0);
                    }
                    sql = "SELECT usr_1, login_1, usr_2, login_2, p1, p2, p3, p4, p5, time, obj, type, status, ophash FROM " + OP_OBJ_HISTORY_TABLE + " WHERE " + (objType == null ? "" : " type = ? AND ") + dbSchema.generatePKString(OP_OBJ_HISTORY_TABLE, "p%1$d = ?", " AND ", (objType == null ? historyObjectRequest.key.size() : historyObjectRequest.key.size() - 1)) + " ORDER BY sorder " + historyObjectRequest.sort + " LIMIT " + historyObjectRequest.limit;
                    loadHistory(sql, historyObjectRequest);
                    break;
                }
            case HISTORY_BY_TYPE:
                {
                    historyObjectRequest.key = Collections.singletonList(historyObjectRequest.key.get(0));
                    sql = "SELECT usr_1, login_1, usr_2, login_2, p1, p2, p3, p4, p5, time, obj, type, status, ophash FROM " + OP_OBJ_HISTORY_TABLE + " WHERE type = ?" + " ORDER BY sorder " + historyObjectRequest.sort + " LIMIT " + historyObjectRequest.limit;
                    loadHistory(sql, historyObjectRequest);
                    break;
                }
            case HISTORY_ALL:
                {
                    sql = "SELECT usr_1, login_1, usr_2, login_2, p1, p2, p3, p4, p5, time, obj, type, status, ophash FROM " + OP_OBJ_HISTORY_TABLE + " ORDER BY sorder " + historyObjectRequest.sort + " LIMIT " + historyObjectRequest.limit;
                    loadHistory(sql, historyObjectRequest);
                    break;
                }
            case HISTORY_BY_OPERATION_HASH:
                {
                    sql = "SELECT usr_1, login_1, usr_2, login_2, p1, p2, p3, p4, p5, time, obj, type, status, ophash FROM " + OP_OBJ_HISTORY_TABLE + " WHERE ophash = ? ORDER BY sorder " + historyObjectRequest.sort + " LIMIT " + historyObjectRequest.limit;
                    loadHistory(sql, historyObjectRequest);
                    break;
                }
        }
    }

    private StringBuilder getUserSqlRequestString(HistoryObjectRequest historyObjectRequest) {
        StringBuilder userString = new StringBuilder();
        int k = 1;
        for (String key : historyObjectRequest.key) {
            if (key.contains(":")) {
                if (userString.length() == 0) {
                    userString.append(" usr_").append(k).append(" = ? AND login_").append(k).append(" = ? ");
                } else {
                    userString.append(" AND usr_").append(k).append(" = ? AND login_").append(k).append(" = ? ");
                }
            } else {
                if (userString.length() == 0) {
                    userString.append(" usr_").append(k).append(" = ? ");
                } else {
                    userString.append(" AND usr_").append(k).append(" = ? ");
                }
            }
            k++;
        }
        return userString;
    }

    protected void loadHistory(String sql, HistoryObjectRequest historyObjectRequest) {
        Object[] keyObject = null;
        if (historyObjectRequest.key != null) {
            if (historyObjectRequest.historyType.equals(HISTORY_BY_OPERATION_HASH)) {
                keyObject = new Object[] { SecUtils.getHashBytes(historyObjectRequest.key.get(0)) };
            } else {
                keyObject = historyObjectRequest.key.toArray();
                keyObject = generateUserSearchObject(historyObjectRequest, keyObject);
            }
        }
        historyObjectRequest.historySearchResult = jdbcTemplate.query(sql, keyObject, new ResultSetExtractor<List<HistoryEdit>>() {

            @Override
            public List<HistoryEdit> extractData(ResultSet rs) throws SQLException, DataAccessException {
                List<HistoryEdit> result = new LinkedList<>();
                while (rs.next()) {
                    List<String> users = new ArrayList<>();
                    String user = "";
                    for (int i = 1; i <= 4; i++) {
                        if (rs.getString(i) != null) {
                            if (user.length() == 0) {
                                user = rs.getString(i);
                            } else {
                                user += ":" + rs.getString(i);
                            }
                            if (i % 2 == 0) {
                                users.add(user);
                                user = "";
                            }
                        }
                    }
                    List<String> ids = new ArrayList<>();
                    ids.add(rs.getString(12));
                    for (int i = 5; i <= 4 + MAX_KEY_SIZE; i++) {
                        if (rs.getString(i) != null) {
                            ids.add(rs.getString(i));
                        }
                    }
                    HistoryEdit historyObject = new HistoryEdit(users, rs.getString(12), formatter.parseObject(rs.getString(11)), formatFullDate(rs.getTimestamp(10)), HistoryManager.Status.getStatus(rs.getInt(13)), SecUtils.hexify(rs.getBytes(14)));
                    if (historyObject.getStatus().equals(HistoryManager.Status.EDITED)) {
                        historyObject.setDeltaChanges(formatter.fromJsonToTreeMap(rs.getString(11)));
                    }
                    historyObject.setId(ids);
                    result.add(historyObject);
                }
                result = generateHistoryObj(result, historyObjectRequest.sort);
                return result;
            }
        });
    }

    private Object[] generateUserSearchObject(HistoryObjectRequest historyObjectRequest, Object[] keyObject) {
        if (HISTORY_BY_USER.equals(historyObjectRequest.historyType)) {
            int loginSize = 0;
            for (String key : historyObjectRequest.key) {
                if (key.contains(":")) {
                    loginSize++;
                }
            }
            keyObject = new Object[historyObjectRequest.key.size() + loginSize];
            int i = -1;
            for (String user : historyObjectRequest.key) {
                if (user.contains(":")) {
                    String[] args = user.split(":");
                    keyObject[++i] = args[0];
                    keyObject[++i] = args[1];
                } else {
                    if (i == -1) {
                        keyObject[0] = user;
                        i++;
                    } else {
                        if (loginSize == 0) {
                            keyObject[1] = user;
                        } else {
                            keyObject[2] = user;
                        }
                    }
                }
            }
        }
        return keyObject;
    }

    public List<HistoryEdit> generateHistoryObj(List<HistoryEdit> historyList, String sort) {
        List<HistoryEdit> newHistoryList = new ArrayList<>();
        Map<List<String>, HistoryEdit> previousHistoryEditMap = new HashMap<>();
        Map<List<String>, OpObject> originObjectMap = new HashMap<>();
        for (HistoryEdit historyEdit : historyList) {
            OpObject originObject = getPreviousOpObject(originObjectMap.get(historyEdit.id), previousHistoryEditMap.get(historyEdit.id), historyEdit);
            previousHistoryEditMap.put(historyEdit.id, historyEdit);
            newHistoryList.add(historyEdit);
            originObjectMap.put(historyEdit.id, originObject);
        }
        return newHistoryList;
    }

    private String formatFullDate(Date date) {
        if (date == null)
            return null;
        return DATE_FORMAT.format(date);
    }

    protected OpObject getPreviousOpObject(OpObject originObject, HistoryEdit previousHistoryEdit, HistoryEdit historyEdit) {
        if (historyEdit.getStatus().equals(Status.DELETED)) {
            originObject = historyEdit.objEdit;
        } else if (historyEdit.getStatus().equals(Status.EDITED) && originObject == null || historyEdit.getStatus().equals(Status.CREATED) && previousHistoryEdit == null) {
            originObject = blocksManager.getBlockchain().getObjectByName(historyEdit.objType, historyEdit.id.subList(1, historyEdit.id.size()));
            historyEdit.objEdit = originObject;
        } else {
            Map<String, Object> changes = previousHistoryEdit.deltaChanges;
            if (changes == null) {
                historyEdit.objEdit = originObject;
            } else {
                originObject = generateReverseEditObject(originObject, changes);
                if (originObject.getFieldByExpr(OpObject.F_STATE) != null && originObject.getFieldByExpr(OpObject.F_STATE).equals(F_FINAL)) {
                    originObject.setFieldByExpr(OpObject.F_STATE, OpObject.F_OPEN);
                    originObject.remove(F_SUBMITTED_OP_HASH);
                }
                historyEdit.objEdit = originObject;
            }
        }
        return originObject;
    }

    @SuppressWarnings("unchecked")
    public OpObject generateReverseEditObject(OpObject originObject, Map<String, Object> changes) {
        Map<String, Object> changeEdit = (Map<String, Object>) changes.get(OpObject.F_CHANGE);
        Map<String, Object> currentEdit = (Map<String, Object>) changes.get(OpObject.F_CURRENT);
        OpObject prevObj = new OpObject(originObject);
        for (Map.Entry<String, Object> e : changeEdit.entrySet()) {
            String fieldExpr = e.getKey();
            Object op = e.getValue();
            String opId = op.toString();
            if (op instanceof Map) {
                Map.Entry<String, Object> ee = ((Map<String, Object>) op).entrySet().iterator().next();
                opId = ee.getKey();
            }
            if (OP_CHANGE_DELETE.equals(opId)) {
                Object previousObj = getValueForField(fieldExpr, currentEdit);
                prevObj.setFieldByExpr(fieldExpr, previousObj);
            } else if (OP_CHANGE_APPENDMANY.equals(opId)) {
                Object o = prevObj.getFieldByExpr(fieldExpr);
                if (o instanceof List) {
                    List<Object> currentObj = (List<Object>) o;
                    List<Object> appendObjs = (List<Object>) getValueForField(fieldExpr, changeEdit);
                    currentObj.removeAll(appendObjs);
                    prevObj.setFieldByExpr(fieldExpr, currentObj);
                } else if (o instanceof Map) {
                    Map<Object, Object> currentObj = (Map<Object, Object>) o;
                    List<Map<Object, Object>> appendObjs = (List<Map<Object, Object>>) getValueForField(fieldExpr, changeEdit);
                    for (Map<Object, Object> appendObj : appendObjs) {
                        for (Object key : appendObj.keySet()) {
                            currentObj.remove(appendObj.get(key));
                        }
                    }
                    prevObj.setFieldByExpr(fieldExpr, currentObj);
                }
            } else if (OP_CHANGE_APPEND.equals(opId)) {
                Object o = prevObj.getFieldByExpr(fieldExpr);
                if (o instanceof List) {
                    List<Object> currentObj = (List<Object>) o;
                    Object appendObj = getValueForField(fieldExpr, changeEdit);
                    currentObj.remove(appendObj);
                    prevObj.setFieldByExpr(fieldExpr, currentObj);
                } else if (o instanceof Map) {
                    Map<Object, Object> currentObj = (Map<Object, Object>) o;
                    Map<Object, Object> appendObj = (Map<Object, Object>) getValueForField(fieldExpr, changeEdit);
                    for (Object key : appendObj.keySet()) {
                        currentObj.remove(appendObj.get(key));
                    }
                    prevObj.setFieldByExpr(fieldExpr, currentObj);
                }
            } else if (OP_CHANGE_SET.equals(opId)) {
                Object previousObject = getValueForField(fieldExpr, currentEdit);
                prevObj.setFieldByExpr(fieldExpr, previousObject);
            } else if (OP_CHANGE_INCREMENT.equals(opId)) {
                Object currentValue = prevObj.getFieldByExpr(fieldExpr);
                prevObj.setFieldByExpr(fieldExpr, ((Number) currentValue).longValue() - 1);
            }
        }
        return prevObj;
    }

    protected Object getValueForField(String fieldExpr, Map<String, Object> editMap) {
        for (Map.Entry<String, Object> e : editMap.entrySet()) {
            if (e.getKey().equals(fieldExpr)) {
                Object op = e.getValue();
                Object opValue = e.getValue();
                if (op instanceof Map) {
                    @SuppressWarnings("unchecked")
                    Map.Entry<String, Object> ee = ((Map<String, Object>) op).entrySet().iterator().next();
                    opValue = ee.getValue();
                }
                return opValue;
            }
        }
        return null;
    }

    private Object getObjectByStatus(OpObject opObject, Status status) {
        if (status.equals(Status.CREATED)) {
            return null;
        } else if (status.equals(Status.EDITED)) {
            Map<String, Object> editList = new LinkedHashMap<>();
            editList.put(OpObject.F_CHANGE, opObject.getChangedEditFields());
            editList.put(OpObject.F_CURRENT, opObject.getCurrentEditFields());
            PGobject obj = new PGobject();
            obj.setType("jsonb");
            try {
                obj.setValue(formatter.fullObjectToJson(editList));
            } catch (SQLException e) {
                e.printStackTrace();
            }
            return obj;
        } else if (status.equals(Status.DELETED)) {
            PGobject obj = new PGobject();
            obj.setType("jsonb");
            try {
                obj.setValue(formatter.fullObjectToJson(opObject));
            } catch (SQLException e) {
                e.printStackTrace();
            }
            return obj;
        }
        return null;
    }

    private List<Object[]> generateHistoryObjBatch(OpBlock opBlock, OpOperation op, Date date, DeletedObjectCtx hctx) {
        byte[] blockHash = SecUtils.getHashBytes(opBlock.getFullHash());
        List<Object[]> args = new LinkedList<>();
        args.addAll(prepareArgumentsForHistoryBatch(blockHash, op.getCreated(), op, date, Status.CREATED));
        if (hctx != null) {
            for (String key : hctx.deletedObjsCache.keySet()) {
                if (key.equals(op.getHash())) {
                    args.addAll(prepareArgumentsForHistoryBatch(blockHash, hctx.deletedObjsCache.get(key), op, date, Status.DELETED));
                }
            }
        }
        args.addAll(prepareArgumentsForHistoryBatch(blockHash, op.getEdited(), op, date, Status.EDITED));
        return args;
    }

    private List<Object[]> prepareArgumentsForHistoryBatch(byte[] blockHash, List<OpObject> opObjectList, OpOperation op, Date date, Status status) {
        List<Object[]> insertBatch = new ArrayList<>(opObjectList.size());
        for (int i = 0; i < opObjectList.size(); i++) {
            Object[] args = new Object[6 + DBSchemaManager.HISTORY_USERS_SIZE * 2 + DBSchemaManager.MAX_KEY_SIZE];
            args[0] = blockHash;
            args[1] = SecUtils.getHashBytes(op.getRawHash());
            args[2] = op.getType();
            args[3] = date;
            args[4] = getObjectByStatus(opObjectList.get(i), status);
            args[5] = status.getValue();
            for (int userInd = 0; userInd < HISTORY_USERS_SIZE; userInd++) {
                putUserKey(6, userInd, args, op.getSignedBy());
            }
            List<String> objIds = opObjectList.get(i).getId();
            if (objIds.isEmpty()) {
                objIds = new ArrayList<>();
                objIds.add(op.getRawHash());
                objIds.add(String.valueOf(i));
            }
            int k = 6 + DBSchemaManager.HISTORY_USERS_SIZE * 2;
            for (String id : objIds) {
                args[k] = id;
                k++;
            }
            insertBatch.add(args);
        }
        return insertBatch;
    }

    private void putUserKey(int arrInd, int userInd, Object[] args, List<String> ls) {
        if (ls.size() > userInd) {
            String[] un = ls.get(userInd).split(":");
            args[arrInd + userInd * 2] = un[0];
            if (un.length > 1) {
                args[arrInd + userInd * 2 + 1] = un[1];
            }
        }
    }

    public static clreplaced HistoryObjectRequest {

        public String historyType;

        public List<String> key;

        public int limit;

        public String sort;

        public List<HistoryEdit> historySearchResult;

        public HistoryObjectRequest(String historyType, List<String> key, int limit, String sort) {
            this.limit = limit;
            this.historyType = historyType;
            this.key = key;
            this.sort = sort;
        }
    }

    public static clreplaced HistoryEdit {

        private List<String> id;

        private List<String> userId;

        private String objType;

        private OpObject objEdit;

        private TreeMap<String, Object> deltaChanges;

        private String date;

        private Status status;

        private String opHash;

        public HistoryEdit(List<String> userId, String objType, OpObject objEdit, String date, Status status, String ophash) {
            this.userId = userId;
            this.objType = objType;
            this.objEdit = objEdit;
            this.date = date;
            this.status = status;
            this.opHash = ophash;
        }

        public List<String> getId() {
            return id;
        }

        public void setId(List<String> id) {
            this.id = id;
        }

        public List<String> getUserId() {
            return userId;
        }

        public void setUserId(List<String> userId) {
            this.userId = userId;
        }

        public String getObjType() {
            return objType;
        }

        public void setObjType(String objType) {
            this.objType = objType;
        }

        public OpObject getObjEdit() {
            return objEdit;
        }

        public void setObjEdit(OpObject objEdit) {
            this.objEdit = objEdit;
        }

        public TreeMap<String, Object> getDeltaChanges() {
            return deltaChanges;
        }

        public void setDeltaChanges(TreeMap<String, Object> deltaChanges) {
            this.deltaChanges = deltaChanges;
        }

        public String getDate() {
            return date;
        }

        public void setDate(String date) {
            this.date = date;
        }

        public Status getStatus() {
            return status;
        }

        public void setStatus(Status status) {
            this.status = status;
        }

        public String getOpHash() {
            return opHash;
        }
    }

    public enum Status {

        CREATED(0), DELETED(1), EDITED(2), NOT_SPECIFIED(3);

        private final int value;

        Status(final int newValue) {
            value = newValue;
        }

        public int getValue() {
            return value;
        }

        public static Status getStatus(int value) {
            switch(value) {
                case 0:
                    {
                        return CREATED;
                    }
                case 1:
                    {
                        return DELETED;
                    }
                case 2:
                    {
                        return EDITED;
                    }
                default:
                    {
                        return NOT_SPECIFIED;
                    }
            }
        }
    }
}

19 Source : DBConsensusManager.java
with Apache License 2.0
from OpenPlaceReviews

@Service
public clreplaced DBConsensusManager {

    protected static final Log LOGGER = LogFactory.getLog(DBConsensusManager.clreplaced);

    // check SimulateSuperblockCompactSequences to verify numbers
    @Autowired
    private JdbcTemplate jdbcTemplate;

    @Autowired
    private TransactionTemplate txTemplate;

    @Autowired
    private DBSchemaManager dbSchema;

    @Autowired
    private FileBackupManager backupManager;

    @Autowired
    private JsonFormatter formatter;

    @Autowired
    private LogOperationService logSystem;

    @Autowired
    private SettingsManager settingsManager;

    private Map<String, OpBlock> blocks = new ConcurrentHashMap<String, OpBlock>();

    private Map<String, OpBlock> orphanedBlocks = new ConcurrentHashMap<String, OpBlock>();

    private Map<String, SuperblockDbAccess> dbSuperBlocks = new ConcurrentHashMap<>();

    private OpBlockChain dbManagedChain = null;

    private OpBlockchainRules rules;

    public Map<String, OpBlock> getOrphanedBlocks() {
        return orphanedBlocks;
    }

    protected String getHexFromPgObject(PGobject o) {
        String s = o.getValue();
        if (s == null) {
            return "";
        }
        if (!s.startsWith("\\x")) {
            throw new UnsupportedOperationException();
        }
        return s.substring(2);
    }

    public String getSuperblockHash() {
        return dbManagedChain.getSuperBlockHash();
    }

    // mainchain could change
    public OpBlockChain init(MetadataDb metadataDB) {
        settingsManager.initPreferences();
        dbSchema.initializeDatabaseSchema(metadataDB, jdbcTemplate);
        backupManager.init();
        rules = new OpBlockchainRules(formatter, logSystem);
        LOGGER.info("... Loading block headers ...");
        dbManagedChain = loadBlockHeadersAndBuildMainChain(rules);
        LOGGER.info(String.format("+++ Loaded %d block headers +++", blocks.size()));
        LinkedList<OpBlock> topBlockInfo = selectTopBlockFromOrphanedBlocks(dbManagedChain);
        // LinkedList<OpBlock> topBlockInfo = new LinkedList<OpBlock>();
        if (!topBlockInfo.isEmpty()) {
            LOGGER.info(String.format("### Selected main blockchain with '%s' and %d id. Orphaned blocks %d. ###", topBlockInfo.getLast().getRawHash(), topBlockInfo.getLast().getBlockId(), orphanedBlocks.size()));
        } else {
            LOGGER.info(String.format("### Selected main blockchain with '%s' and %d id. Orphaned blocks %d. ###", dbManagedChain.getLastBlockRawHash(), dbManagedChain.getLastBlockId(), orphanedBlocks.size()));
        }
        LOGGER.info("... Loading blocks from database ...");
        OpBlockChain topChain = loadBlocks(topBlockInfo, dbManagedChain, rules);
        LOGGER.info(String.format("### Loaded %d blocks ###", topChain.getSuperblockSize()));
        OpBlockChain blcQueue = new OpBlockChain(topChain, rules);
        LOGGER.info("... Loading operation queue  ...");
        int[] ops = new int[1];
        jdbcTemplate.query("SELECT content from " + OPERATIONS_TABLE + " where blocks is null order by dbid asc ", new RowCallbackHandler() {

            @Override
            public void processRow(ResultSet rs) throws SQLException {
                ops[0]++;
                OpOperation op = formatter.parseOperation(rs.getString(1));
                op.makeImmutable();
                blcQueue.addOperation(op);
            }
        });
        LOGGER.info(String.format("... Loaded operation %d into queue  ...", ops[0]));
        LOGGER.info(String.format("+++ Database blockchain initialized +++"));
        return blcQueue;
    }

    public OpIndexColumn getIndex(String type, String columnId) {
        return dbSchema.getIndex(type, columnId);
    }

    public Collection<OpIndexColumn> getIndicesForType(String type) {
        return dbSchema.getIndicesForType(type);
    }

    private OpBlockChain loadBlocks(List<OpBlock> topBlockInfo, final OpBlockChain newParent, final OpBlockchainRules rules) {
        if (topBlockInfo.size() == 0) {
            return newParent;
        }
        OpBlockChain blc = new OpBlockChain(newParent, rules);
        for (OpBlock b : topBlockInfo) {
            String blockHash = b.getRawHash();
            OpBlock rawBlock = loadBlock(blockHash);
            OpBlock replicateBlock = blc.replicateBlock(rawBlock);
            if (replicateBlock == null) {
                throw new IllegalStateException("Could not replicate block " + blockHash + " " + formatter.toJson(rawBlock));
            }
        }
        return blc;
    }

    private OpBlock loadBlock(String blockHash) {
        List<OpBlock> blocks = jdbcTemplate.query("SELECT content from " + BLOCKS_TABLE + " where hash = ? ", new Object[] { SecUtils.getHashBytes(blockHash) }, new RowMapper<OpBlock>() {

            @Override
            public OpBlock mapRow(ResultSet rs, int rowNum) throws SQLException {
                OpBlock rawBlock = formatter.parseBlock(rs.getString(1));
                rawBlock.makeImmutable();
                return rawBlock;
            }
        });
        if (blocks.size() > 1) {
            throw new UnsupportedOperationException("Duplicated blocks for the same hash: " + blockHash);
        }
        OpBlock rawBlock = blocks.size() == 0 ? null : blocks.get(0);
        return rawBlock;
    }

    private OpBlockChain compactTwoDBAccessed(OpBlockChain blc) {
        LOGGER.info(String.format("Compacting db superblock '%s' into  superblock '%s'", blc.getParent().getSuperBlockHash(), blc.getSuperBlockHash()));
        SuperblockDbAccess dbSB = dbSuperBlocks.get(blc.getSuperBlockHash());
        SuperblockDbAccess dbPSB = dbSuperBlocks.get(blc.getParent().getSuperBlockHash());
        List<OpBlock> blockHeaders = new ArrayList<OpBlock>();
        blockHeaders.addAll(blc.getSuperblockHeaders());
        blockHeaders.addAll(blc.getParent().getSuperblockHeaders());
        String newSuperblockHash = OpBlockchainRules.calculateSuperblockHash(blockHeaders.size(), blc.getLastBlockRawHash());
        byte[] sbHashCurrent = SecUtils.getHashBytes(blc.getSuperBlockHash());
        byte[] sbHashParent = SecUtils.getHashBytes(blc.getParent().getSuperBlockHash());
        byte[] sbHashNew = SecUtils.getHashBytes(newSuperblockHash);
        return txTemplate.execute(new TransactionCallback<OpBlockChain>() {

            @Override
            public OpBlockChain doInTransaction(TransactionStatus status) {
                dbSB.markreplacedtale(true);
                dbPSB.markreplacedtale(true);
                jdbcTemplate.update("UPDATE " + BLOCKS_TABLE + " set superblock = ? WHERE superblock = ? ", sbHashNew, sbHashCurrent);
                jdbcTemplate.update("UPDATE " + BLOCKS_TABLE + " set superblock = ? WHERE superblock = ? ", sbHashNew, sbHashParent);
                jdbcTemplate.update("UPDATE " + OPERATIONS_TABLE + " set superblock = ? WHERE superblock = ? ", sbHashNew, sbHashCurrent);
                jdbcTemplate.update("UPDATE " + OPERATIONS_TABLE + " set superblock = ? WHERE superblock = ? ", sbHashNew, sbHashParent);
                for (String objTable : dbSchema.getObjectTables()) {
                    jdbcTemplate.update("UPDATE " + objTable + " set superblock = ?  WHERE superblock = ? ", sbHashNew, sbHashCurrent);
                    jdbcTemplate.update("UPDATE " + objTable + " set superblock = ?  WHERE superblock = ? ", sbHashNew, sbHashParent);
                }
                OpBlockChain res = new OpBlockChain(blc.getParent().getParent(), blockHeaders, createDbAccess(newSuperblockHash, blockHeaders), blc.getRules());
                // on catch
                // dbSB.markreplacedtale(false);
                // dbPSB.markreplacedtale(false);
                return res;
            }
        });
    }

    protected clreplaced SuperblockDbSpliterator implements Spliterator<Map.Entry<CompoundKey, OpObject>> {

        private static final int BATCH_SIZE = 250;

        private SqlRowSet rs;

        private SuperblockDbAccess dbAccess;

        private final int keySize;

        private LinkedList<Map.Entry<CompoundKey, OpObject>> results = new LinkedList<>();

        private boolean end;

        private boolean onlyKeys;

        SuperblockDbSpliterator(SuperblockDbAccess dbAccess, int keySize, boolean onlyKeys, SqlRowSet rowSet) throws DBStaleException {
            this.dbAccess = dbAccess;
            this.keySize = keySize;
            this.onlyKeys = onlyKeys;
            this.rs = rowSet;
            readEntries();
        }

        private boolean readEntries() throws DBStaleException {
            if (end) {
                return true;
            }
            dbAccess.readLock.lock();
            try {
                dbAccess.checkNotStale();
                final List<String> ls = new ArrayList<String>(5);
                int cnt = 0;
                while (cnt++ < BATCH_SIZE) {
                    if (!rs.next()) {
                        end = true;
                        return true;
                    }
                    ls.clear();
                    for (int i = 0; i < keySize; i++) {
                        ls.add(rs.getString(i + 4));
                    }
                    final CompoundKey k = new CompoundKey(0, ls);
                    final OpObject obj;
                    if (!onlyKeys) {
                        String cont = rs.getString(1);
                        obj = cont == null ? new OpObject(true) : formatter.parseObject(cont);
                    } else {
                        obj = new OpObject(rs.getBoolean(1));
                    }
                    obj.setParentOp(rs.getString(2), SecUtils.hexify((byte[]) rs.getObject(3)));
                    results.add(new Map.Entry<CompoundKey, OpObject>() {

                        @Override
                        public CompoundKey getKey() {
                            return k;
                        }

                        @Override
                        public OpObject getValue() {
                            return obj;
                        }

                        @Override
                        public OpObject setValue(OpObject value) {
                            throw new UnsupportedOperationException();
                        }
                    });
                }
            } finally {
                dbAccess.readLock.unlock();
            }
            return false;
        }

        @Override
        public boolean tryAdvance(Consumer<? super Map.Entry<CompoundKey, OpObject>> action) {
            boolean empty = results.isEmpty();
            if (empty) {
                readEntries();
                empty = results.isEmpty();
            }
            if (!empty) {
                action.accept(results.pop());
                return true;
            }
            return false;
        }

        @Override
        public Spliterator<Entry<CompoundKey, OpObject>> trySplit() {
            return null;
        }

        @Override
        public long estimateSize() {
            return Long.MAX_VALUE;
        }

        @Override
        public int characteristics() {
            return 0;
        }
    }

    public clreplaced DBStaleException extends RuntimeException {

        public DBStaleException(String string) {
            super(string);
        }

        private static final long serialVersionUID = 327630066462749799L;
    }

    protected clreplaced SuperblockDbAccess implements BlockDbAccessInterface {

        protected final String superBlockHash;

        protected final List<OpBlock> blockHeaders;

        private final ReentrantReadWriteLock readWriteLock;

        private final ReadLock readLock;

        private final byte[] sbhash;

        private AtomicBoolean staleAccess = new AtomicBoolean(false);

        public SuperblockDbAccess(String superBlockHash, Collection<OpBlock> blockHeaders) {
            this.superBlockHash = superBlockHash;
            sbhash = SecUtils.getHashBytes(superBlockHash);
            this.blockHeaders = new ArrayList<OpBlock>(blockHeaders);
            this.readWriteLock = new ReentrantReadWriteLock();
            readLock = this.readWriteLock.readLock();
            dbSuperBlocks.put(superBlockHash, this);
        }

        public boolean markreplacedtale(boolean stale) throws DBStaleException {
            WriteLock lock = readWriteLock.writeLock();
            lock.lock();
            try {
                staleAccess.set(stale);
                return true;
            } finally {
                lock.unlock();
            }
        }

        @Override
        public OpObject getObjectById(String type, CompoundKey k, boolean content) throws DBStaleException {
            readLock.lock();
            try {
                checkNotStale();
                int sz = k.size();
                Object[] o = new Object[sz + 2];
                o[0] = sbhash;
                o[1] = type;
                k.toArray(o, 2);
                String table = dbSchema.getTableByType(type);
                int keySizeByTable = dbSchema.getKeySizeByTable(table);
                if (sz > keySizeByTable || sz == 0) {
                    throw new UnsupportedOperationException();
                }
                String nullFields = "";
                for (int i = sz; i < keySizeByTable; i++) {
                    nullFields += " and p" + (i + 1) + " is null ";
                }
                String s = "select type, ophash" + (content ? ", content" : "") + " from " + table + " where superblock = ? and type = ? and " + dbSchema.generatePKString(table, "p%1$d = ?", " and ", sz) + nullFields + " order by sblockid desc";
                return jdbcTemplate.query(s, o, new ResultSetExtractor<OpObject>() {

                    @Override
                    public OpObject extractData(ResultSet rs) throws SQLException, DataAccessException {
                        if (!rs.next()) {
                            return null;
                        }
                        OpObject obj;
                        if (!content) {
                            // this is not 100% correct
                            obj = new OpObject(false);
                        } else {
                            String cnt = rs.getString(3);
                            if (cnt == null) {
                                obj = new OpObject(true);
                            } else {
                                obj = formatter.parseObject(cnt);
                            }
                        }
                        obj.setParentOp(rs.getString(1), SecUtils.hexify(rs.getBytes(2)));
                        return obj;
                    }
                });
            } finally {
                readLock.unlock();
            }
        }

        private void checkNotStale() throws DBStaleException {
            if (staleAccess.get()) {
                throw new DBStaleException("Superblock is stale : " + SecUtils.hexify(sbhash));
            }
        }

        public Stream<Map.Entry<CompoundKey, OpObject>> streamObjects(String type, int limit, boolean onlyKeys, Object... extraParams) throws DBStaleException {
            readLock.lock();
            try {
                checkNotStale();
                int l = (extraParams == null ? 0 : extraParams.length);
                Object[] o = new Object[2 + Math.max(l - 1, 0)];
                o[0] = sbhash;
                o[1] = type;
                String cond = null;
                for (int i = 0; i < l; i++) {
                    if (i == 0) {
                        cond = extraParams[i].toString();
                    } else {
                        o[1 + i] = extraParams[i];
                    }
                }
                String objTable = dbSchema.getTableByType(type);
                final int keySize = dbSchema.getKeySizeByTable(objTable);
                String cntField = "content";
                if (onlyKeys) {
                    cntField = "case when content is null then true else false end";
                }
                String sql = "select " + cntField + ", type, ophash, " + dbSchema.generatePKString(objTable, "p%1$d", ", ") + "  from " + objTable + " where superblock = ? and type = ? " + (cond == null ? "" : " and " + cond);
                // so the result can simply override and get latest version
                sql = sql + " order by sblockid asc";
                if (limit > 0) {
                    sql = sql + " limit " + limit;
                }
                final SqlRowSet rs = jdbcTemplate.queryForRowSet(sql, o);
                return StreamSupport.stream(new SuperblockDbSpliterator(this, keySize, onlyKeys, rs), false);
            } finally {
                readLock.unlock();
            }
        }

        public int countObjects(String type, Object... extraParams) throws DBStaleException {
            readLock.lock();
            try {
                checkNotStale();
                int l = (extraParams == null ? 0 : extraParams.length);
                Object[] o = new Object[2 + Math.max(l - 1, 0)];
                o[0] = sbhash;
                o[1] = type;
                String cond = null;
                for (int i = 0; i < l; i++) {
                    if (i == 0) {
                        cond = extraParams[i].toString();
                    } else {
                        o[1 + i] = extraParams[i];
                    }
                }
                String objTable = dbSchema.getTableByType(type);
                String sql = "select count(*) from " + objTable + " where superblock = ? and type = ? " + (cond == null ? "" : " and " + cond);
                return jdbcTemplate.queryForObject(sql, o, Number.clreplaced).intValue();
            } finally {
                readLock.unlock();
            }
        }

        @Override
        public OpOperation getOperation(String rawHash, boolean strict) throws DBStaleException {
            readLock.lock();
            try {
                checkNotStale();
                OpOperation[] op = new OpOperation[1];
                Object ophash;
                String sqlCond = "";
                if (strict) {
                    ophash = SecUtils.getHashBytes(rawHash);
                    sqlCond = "hash = ?";
                } else {
                    ophash = rawHash;
                    sqlCond = "encode(hash, 'hex') like (? || '%')";
                }
                jdbcTemplate.query("SELECT content from " + OPERATIONS_TABLE + " where superblock = ? and " + sqlCond, new RowCallbackHandler() {

                    @Override
                    public void processRow(ResultSet rs) throws SQLException {
                        op[0] = formatter.parseOperation(rs.getString(1));
                    }
                }, sbhash, ophash);
                return op[0];
            } finally {
                readLock.unlock();
            }
        }

        @Override
        public Deque<OpBlock> getAllBlocks(Collection<OpBlock> blockHeaders) {
            boolean isSuperblockReferenceActive = false;
            readLock.lock();
            try {
                isSuperblockReferenceActive = !staleAccess.get();
            } finally {
                readLock.unlock();
            }
            if (isSuperblockReferenceActive) {
            // to do faster to load by superblock reference, so it could be 1 sql
            // but it need to handle correctly DBStaleException
            }
            LinkedList<OpBlock> blocks = new LinkedList<OpBlock>();
            for (OpBlock b : blockHeaders) {
                OpBlock lb = loadBlock(b.getRawHash());
                if (lb == null) {
                    throw new IllegalStateException(String.format("Couldn't load '%s' block from db", b.getRawHash()));
                }
                blocks.add(lb);
            }
            return blocks;
        }

        @Override
        public OpBlock getBlockByHash(String rawHash) {
            return loadBlock(rawHash);
        }

        @Override
        public Collection<String> getObjectTypes() {
            readLock.lock();
            try {
                Set<String> types = new LinkedHashSet<String>();
                checkNotStale();
                jdbcTemplate.query("SELECT distinct type from " + OPERATIONS_TABLE + " where superblock = ?", new RowCallbackHandler() {

                    @Override
                    public void processRow(ResultSet rs) throws SQLException {
                        if (rs.next()) {
                            types.add(rs.getString(1));
                        }
                    }
                }, sbhash);
                return types;
            } finally {
                readLock.unlock();
            }
        }
    }

    protected BlockDbAccessInterface createDbAccess(String superblock, Collection<OpBlock> blockHeaders) {
        return new SuperblockDbAccess(superblock, blockHeaders);
    }

    private OpBlockChain loadBlockHeadersAndBuildMainChain(final OpBlockchainRules rules) {
        OpBlockChain[] res = new OpBlockChain[] { OpBlockChain.NULL };
        jdbcTemplate.query("SELECT hash, phash, blockid, superblock, header, pg_column_size(content), opcount, " + "objdeleted, objedited, objadded from " + BLOCKS_TABLE + " order by blockId asc", new RowCallbackHandler() {

            LinkedList<OpBlock> blockHeaders = new LinkedList<OpBlock>();

            @Override
            public void processRow(ResultSet rs) throws SQLException {
                String blockHash = SecUtils.hexify(rs.getBytes(1));
                String pblockHash = SecUtils.hexify(rs.getBytes(2));
                String superblock = SecUtils.hexify(rs.getBytes(4));
                OpBlock parentBlockHeader = blocks.get(pblockHash);
                OpBlock blockHeader = formatter.parseBlock(rs.getString(5));
                blockHeader.makeImmutable();
                blocks.put(blockHash, blockHeader);
                if (!OUtils.isEmpty(pblockHash) && parentBlockHeader == null) {
                    LOGGER.error(String.format("Orphaned block '%s' without parent '%s'.", blockHash, pblockHash));
                    orphanedBlocks.put(blockHash, blockHeader);
                    return;
                } else if (OUtils.isEmpty(superblock)) {
                    orphanedBlocks.put(blockHash, blockHeader);
                } else {
                    String lastBlockHash = blockHeaders.size() == 0 ? res[0].getLastBlockRawHash() : blockHeaders.getFirst().getRawHash();
                    blockHeaders.push(blockHeader);
                    String currentSuperblock = OpBlockchainRules.calculateSuperblockHash(blockHeaders.size(), blockHeader.getRawHash());
                    // add to current chain
                    if (!OUtils.equals(pblockHash, lastBlockHash)) {
                        throw new IllegalStateException(String.format("Block '%s'. Illegal parent '%s' != '%s' for superblock '%s'", blockHash, pblockHash, res[0].getLastBlockRawHash(), superblock));
                    }
                    if (OUtils.equals(superblock, currentSuperblock)) {
                        OpBlockChain parent = res[0];
                        res[0] = new OpBlockChain(parent, blockHeaders, createDbAccess(superblock, blockHeaders), rules);
                        blockHeaders.clear();
                    }
                }
            }
        });
        return res[0];
    }

    private boolean isConnected(OpBlock bi, String lastBlockRawHash) {
        if (bi.getBlockId() == 0) {
            return lastBlockRawHash.length() == 0;
        }
        if (bi.getRawHash().equals(lastBlockRawHash)) {
            return true;
        }
        String prevRawHash = bi.getPrevRawHash();
        OpBlock parentBlock = blocks.get(prevRawHash);
        if (parentBlock != null) {
            return isConnected(parentBlock, lastBlockRawHash);
        }
        return false;
    }

    private LinkedList<OpBlock> selectTopBlockFromOrphanedBlocks(OpBlockChain prev) {
        OpBlock topBlockInfo = null;
        String lastBlockRawHash = prev.getLastBlockRawHash();
        for (OpBlock bi : orphanedBlocks.values()) {
            boolean isNewer = false;
            if (topBlockInfo == null) {
                isNewer = true;
            } else if (topBlockInfo.getBlockId() < bi.getBlockId()) {
                isNewer = true;
            } else if (topBlockInfo.getBlockId() == bi.getBlockId() && topBlockInfo.getRawHash().compareTo(bi.getRawHash()) > 0) {
                isNewer = true;
            }
            if (isNewer && isConnected(bi, lastBlockRawHash)) {
                topBlockInfo = bi;
            }
        }
        // returns in order from the oldest to the newest
        LinkedList<OpBlock> blockList = new LinkedList<OpBlock>();
        if (topBlockInfo != null && topBlockInfo.getBlockId() > prev.getLastBlockId()) {
            OpBlock blockInfo = topBlockInfo;
            LinkedList<String> blocksInfoLst = new LinkedList<String>();
            while (blockInfo != null) {
                if (OUtils.equals(blockInfo.getRawHash(), lastBlockRawHash)) {
                    return blockList;
                }
                orphanedBlocks.remove(blockInfo.getRawHash());
                blockList.addFirst(blockInfo);
                blocksInfoLst.addFirst(blockInfo.getRawHash());
                blockInfo = blocks.get(blockInfo.getPrevRawHash());
            }
            if (OUtils.isEmpty(lastBlockRawHash)) {
                return blockList;
            }
            throw new IllegalStateException(String.format("Top selected block '%s' is not connected to superblock '%s'", blocksInfoLst.toString(), prev.getLastBlockRawHash()));
        }
        return blockList;
    }

    public void insertBlock(OpBlock opBlock) {
        OpBlock blockheader = OpBlock.createHeader(opBlock, rules);
        PGobject blockObj = new PGobject();
        blockObj.setType("jsonb");
        PGobject blockHeaderObj = new PGobject();
        blockHeaderObj.setType("jsonb");
        try {
            blockObj.setValue(formatter.toJson(opBlock));
            blockHeaderObj.setValue(formatter.fullObjectToJson(blockheader));
        } catch (SQLException e) {
            throw new IllegalArgumentException(e);
        }
        byte[] blockHash = SecUtils.getHashBytes(opBlock.getFullHash());
        String rawHash = SecUtils.hexify(blockHash);
        byte[] prevBlockHash = SecUtils.getHashBytes(opBlock.getStringValue(OpBlock.F_PREV_BLOCK_HASH));
        // String rawPrevBlockHash = SecUtils.hexify(prevBlockHash);
        txTemplate.execute(new TransactionCallback<Void>() {

            @Override
            public Void doInTransaction(TransactionStatus status) {
                int added = 0, edited = 0, deleted = 0;
                for (OpOperation opOperation : opBlock.getOperations()) {
                    added += opOperation.getCreated().size();
                    edited += opOperation.getEdited().size();
                    deleted += opOperation.getDeleted().size();
                }
                jdbcTemplate.update("INSERT INTO " + BLOCKS_TABLE + " (hash, phash, blockid, header, content, opcount, objdeleted, objedited, objadded) " + "VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)", blockHash, prevBlockHash, opBlock.getBlockId(), blockHeaderObj, blockObj, opBlock.getOperations().size(), deleted, added, edited);
                for (OpOperation o : opBlock.getOperations()) {
                    int upd = jdbcTemplate.update("UPDATE " + OPERATIONS_TABLE + " set blocks = blocks || ? where hash = ?", blockHash, SecUtils.getHashBytes(o.getHash()));
                    if (upd == 0) {
                        throw new IllegalArgumentException(String.format("Can't create block '%s' cause op '%s' doesn't exist", opBlock.getRawHash(), o.getHash()));
                    }
                }
                return null;
            }
        });
        backupManager.insertBlock(opBlock);
        blocks.put(rawHash, blockheader);
        orphanedBlocks.put(rawHash, blockheader);
    }

    public OpBlockChain saveMainBlockchain(OpBlockChain blc) {
        // find and saved last not saved part of the chain
        OpBlockChain lastNotSaved = null;
        OpBlockChain beforeLast = null;
        boolean parentInOrphanedList = true;
        while (!blc.isNullBlock() && !blc.isDbAccessed()) {
            beforeLast = lastNotSaved;
            lastNotSaved = blc;
            if (parentInOrphanedList) {
                for (OpBlock header : blc.getSuperblockHeaders()) {
                    OpBlock existing = orphanedBlocks.remove(header.getRawHash());
                    if (existing == null) {
                        parentInOrphanedList = false;
                        break;
                    }
                }
            }
            blc = blc.getParent();
        }
        if (lastNotSaved != null && lastNotSaved.getSuperblockSize() >= settingsManager.OPENDB_SUPERBLOCK_SIZE.get()) {
            OpBlockChain saved = saveSuperblock(lastNotSaved);
            if (beforeLast != null) {
                if (!beforeLast.changeToEqualParent(saved)) {
                    throw new IllegalStateException("Can't change parent " + lastNotSaved.getSuperBlockHash() + " " + saved.getSuperBlockHash());
                }
            } else {
                return saved;
            }
        }
        return blc;
    }

    private OpBlockChain saveSuperblock(OpBlockChain blc) {
        blc.validateLocked();
        String superBlockHashStr = blc.getSuperBlockHash();
        LOGGER.info(String.format("Save superblock %s ", superBlockHashStr));
        byte[] superBlockHash = SecUtils.getHashBytes(blc.getSuperBlockHash());
        Collection<OpBlock> blockHeaders = blc.getSuperblockHeaders();
        return txTemplate.execute(new TransactionCallback<OpBlockChain>() {

            @Override
            public OpBlockChain doInTransaction(TransactionStatus status) {
                Map<String, Long> opsId = new HashMap<String, Long>();
                for (OpBlock block : blc.getSuperblockFullBlocks()) {
                    byte[] blHash = SecUtils.getHashBytes(block.getFullHash());
                    // replacedign parent hash only for last block
                    // String blockRawHash = SecUtils.hexify(blHash);
                    // LOGGER.info(String.format("Update block %s to superblock %s ", o.getHash(), superBlockHash));
                    jdbcTemplate.update("UPDATE " + BLOCKS_TABLE + " set superblock = ? where hash = ?", superBlockHash, blHash);
                    int order = 0;
                    int bid = block.getBlockId();
                    for (OpOperation op : block.getOperations()) {
                        long l = OUtils.combine(bid, order);
                        opsId.put(op.getRawHash(), l);
                        jdbcTemplate.update("UPDATE " + OPERATIONS_TABLE + " set superblock = ?, sblockid = ?, sorder = ? where hash = ?", superBlockHash, bid, order, SecUtils.getHashBytes(op.getRawHash()));
                        order++;
                    }
                }
                for (String type : blc.getRawSuperblockTypes()) {
                    Stream<Map.Entry<CompoundKey, OpObject>> objects = blc.getRawSuperblockObjects(type);
                    Collection<OpIndexColumn> indexes = dbSchema.getIndicesForType(type);
                    List<OpIndexColumn> dbIndexes = new ArrayList<OpIndexColumn>();
                    for (OpIndexColumn index : indexes) {
                        if (index.getIdIndex() < 0) {
                            dbIndexes.add(index);
                        }
                    }
                    List<Object[]> insertBatch = prepareInsertObjBatch(objects, type, superBlockHash, opsId, dbIndexes);
                    String table = dbSchema.getTableByType(type);
                    dbSchema.insertObjIntoTableBatch(insertBatch, table, jdbcTemplate, dbIndexes);
                }
                OpBlockChain dbchain = new OpBlockChain(blc.getParent(), blockHeaders, createDbAccess(superBlockHashStr, blockHeaders), blc.getRules());
                return dbchain;
            }
        });
    }

    protected List<Object[]> prepareInsertObjBatch(Stream<Map.Entry<CompoundKey, OpObject>> objects, String type, byte[] superBlockHash, Map<String, Long> opsId, Collection<OpIndexColumn> indexes) {
        List<Object[]> insertBatch = new ArrayList<>();
        String tableByType = dbSchema.getTableByType(type);
        int ksize = dbSchema.getKeySizeByTable(tableByType);
        Iterator<Entry<CompoundKey, OpObject>> it = objects.iterator();
        Connection conn = null;
        try {
            conn = jdbcTemplate.getDataSource().getConnection();
            while (it.hasNext()) {
                Entry<CompoundKey, OpObject> e = it.next();
                CompoundKey pkey = e.getKey();
                OpObject obj = e.getValue();
                // OpObject.NULL doesn't have parent hash otherwise it should be a separate object
                Long l = opsId.get(obj.getParentHash());
                if (obj == OpObject.NULL) {
                    l = 0l;
                }
                if (l == null) {
                    throw new IllegalArgumentException(String.format("Not found op: '%s'", obj.getParentHash()));
                }
                int sblockid = OUtils.first(l);
                int sorder = OUtils.second(l);
                if (pkey.size() > ksize) {
                    throw new UnsupportedOperationException("Key is too long to be stored: " + pkey.toString());
                }
                Object[] args = new Object[6 + ksize + indexes.size()];
                int ind = 0;
                args[ind++] = type;
                String ophash = obj.getParentHash();
                args[ind++] = SecUtils.getHashBytes(ophash);
                args[ind++] = superBlockHash;
                args[ind++] = sblockid;
                args[ind++] = sorder;
                if (!obj.isDeleted()) {
                    PGobject contentObj = new PGobject();
                    contentObj.setType("jsonb");
                    try {
                        contentObj.setValue(formatter.objToJson(obj));
                    } catch (SQLException es) {
                        throw new IllegalArgumentException(es);
                    }
                    args[ind++] = contentObj;
                } else {
                    args[ind++] = null;
                }
                for (OpIndexColumn index : indexes) {
                    if (!obj.isDeleted()) {
                        args[ind++] = index.evalDBValue(obj, conn);
                    } else {
                        args[ind++] = null;
                    }
                }
                pkey.toArray(args, ind);
                insertBatch.add(args);
            }
        } catch (SQLException e) {
            throw new IllegalArgumentException();
        } finally {
            if (conn != null) {
                try {
                    conn.close();
                } catch (SQLException e) {
                    throw new IllegalArgumentException(e);
                }
            }
        }
        return insertBatch;
    }

    public OpBlockChain compact(int prevSize, OpBlockChain blc, boolean db) {
        if (blc == null || blc.isNullBlock() || blc.getParent().isNullBlock()) {
            return blc;
        }
        OpBlockChain compactedParent = null;
        if (blc.isDbAccessed() == blc.getParent().isDbAccessed()) {
            compactedParent = compact(blc.getSuperblockSize(), blc.getParent(), db);
            // only 1 compact at a time
            boolean compact = compactedParent == blc.getParent();
            compact = compact && ((double) blc.getSuperblockSize() + settingsManager.OPENDB_COMPACT_COEFICIENT.get() * prevSize) > ((double) blc.getParent().getSuperblockSize());
            if (compact) {
                LOGGER.info("Chain to compact: ");
                printBlockChain(blc);
                // See @SimulateSuperblockCompactSequences
                if (blc.isDbAccessed() && db) {
                    // here we need to lock all db access of 2 blocks and run update in 1 transaction
                    return compactTwoDBAccessed(blc);
                } else {
                    LOGGER.info(String.format("Compact runtime superblock '%s' into  superblock '%s' ", blc.getParent().getSuperBlockHash(), blc.getSuperBlockHash()));
                    blc = new OpBlockChain(blc, blc.getParent(), blc.getRules());
                    return blc;
                }
            }
        } else {
            // redirect compact to parent
            compactedParent = compact(0, blc.getParent(), db);
        }
        if (blc.getParent() != compactedParent) {
            blc.changeToEqualParent(compactedParent);
        }
        return blc;
    }

    private void printBlockChain(OpBlockChain blc) {
        List<String> superBlocksChain = new ArrayList<String>();
        OpBlockChain p = blc;
        while (p != null && !p.isNullBlock()) {
            String sh = p.getSuperBlockHash();
            if (sh.startsWith("00")) {
                while (sh.startsWith("00")) {
                    sh = sh.substring(2);
                }
                sh = "0*" + sh;
            }
            if (sh.length() > 10) {
                sh = sh.substring(0, 10);
            }
            if (p.isDbAccessed()) {
                sh = "db-" + sh;
            }
            superBlocksChain.add(sh);
            p = p.getParent();
        }
        LOGGER.info(String.format("Runtime chain %s", superBlocksChain));
    }

    public int removeOperations(Set<String> ops) {
        return txTemplate.execute(new TransactionCallback<Integer>() {

            @Override
            public Integer doInTransaction(TransactionStatus status) {
                int deleted = 0;
                // simple approach without using transaction isolations
                for (String op : ops) {
                    deleted += jdbcTemplate.update("WITH moved_rows AS ( DELETE FROM " + OPERATIONS_TABLE + "     a WHERE hash = ? and (blocks = '{}' or blocks is null) RETURNING a.*) " + " INSERT INTO " + OPERATIONS_TRASH_TABLE + " (id, hash, time, type, content) SELECT dbid, hash, now(), type, content FROM moved_rows", SecUtils.getHashBytes(op));
                }
                return deleted;
            }
        });
    }

    public boolean removeFullBlock(OpBlock block) {
        return txTemplate.execute(new TransactionCallback<Boolean>() {

            @Override
            public Boolean doInTransaction(TransactionStatus status) {
                byte[] blockHash = SecUtils.getHashBytes(block.getRawHash());
                int upd = jdbcTemplate.update("WITH moved_rows AS ( DELETE FROM " + BLOCKS_TABLE + " a WHERE hash = ? and superblock is null RETURNING a.*) " + " INSERT INTO " + BLOCKS_TRASH_TABLE + " (hash, phash, blockid, time, content) SELECT hash, phash, blockid, now(), content FROM moved_rows", blockHash);
                if (upd != 0) {
                    // to do:
                    // here we need to decide what to do with operations with empty blocks[] (they will be added to the queue after restart otherwise)
                    for (OpOperation o : block.getOperations()) {
                        jdbcTemplate.update("UPDATE " + OPERATIONS_TABLE + " set blocks = array_remove(blocks, ?) where hash = ?", blockHash, SecUtils.getHashBytes(o.getRawHash()));
                    }
                    jdbcTemplate.update("DELETE FROM " + OP_OBJ_HISTORY_TABLE + " WHERE blockhash = ?", SecUtils.getHashBytes(block.getFullHash()));
                    orphanedBlocks.remove(block.getRawHash());
                    blocks.remove(block.getRawHash());
                }
                return upd != 0;
            }
        });
    }

    public OpBlockChain unloadSuperblockFromDB(OpBlockChain blc) {
        if (blc.isDbAccessed()) {
            SuperblockDbAccess dba = dbSuperBlocks.get(blc.getSuperBlockHash());
            final OpBlockChain res = new OpBlockChain(blc.getParent(), blc.getRules());
            List<OpBlock> lst = new ArrayList<OpBlock>(blc.getSuperblockFullBlocks());
            byte[] blockHash = SecUtils.getHashBytes(blc.getSuperBlockHash());
            Collections.reverse(lst);
            for (OpBlock block : lst) {
                res.replicateBlock(block);
            }
            return txTemplate.execute(new TransactionCallback<OpBlockChain>() {

                @Override
                public OpBlockChain doInTransaction(TransactionStatus status) {
                    dba.markreplacedtale(true);
                    jdbcTemplate.update("UPDATE " + OPERATIONS_TABLE + " set superblock = NULL where superblock = ?", blockHash);
                    jdbcTemplate.update("UPDATE " + BLOCKS_TABLE + " set superblock = NULL where superblock = ? ", blockHash);
                    for (String objTable : dbSchema.getObjectTables()) {
                        jdbcTemplate.update("DELETE FROM " + objTable + " where superblock = ?", blockHash);
                    }
                    return res;
                }
            });
        }
        return blc;
    }

    public ResourceDTO storeResourceObject(ResourceDTO imageDTO) throws IOException {
        imageDTO.setHash(SecUtils.calculateHashWithAlgo(SecUtils.HASH_SHA256, imageDTO.getMultipartFile().getBytes()));
        if (getResourceObjectIfExists(imageDTO) == null) {
            imageDTO.setAdded(new Date());
            jdbcTemplate.update("INSERT INTO " + EXT_RESOURCE_TABLE + "(hash, extension, cid, added) VALUES (?, ?, ?, ?)", SecUtils.getHashBytes(imageDTO.getHash()), imageDTO.getExtension(), imageDTO.getCid(), imageDTO.getAdded());
        }
        return imageDTO;
    }

    public ResourceDTO storeResourceObject(String ext, String cid, byte[] bytes) throws IOException {
        String hash = SecUtils.calculateHashWithAlgo(SecUtils.HASH_SHA256, bytes);
        ResourceDTO imageDTO = ResourceDTO.of(hash, ext, cid);
        if (getResourceObjectIfExists(imageDTO) == null) {
            imageDTO.setAdded(new Date());
            jdbcTemplate.update("INSERT INTO " + EXT_RESOURCE_TABLE + "(hash, extension, cid, added) VALUES (?, ?, ?, ?)", SecUtils.getHashBytes(imageDTO.getHash()), imageDTO.getExtension(), imageDTO.getCid(), imageDTO.getAdded());
        }
        return imageDTO;
    }

    public ResourceDTO getResourceObjectIfExists(ResourceDTO imageDTO) {
        return jdbcTemplate.query("SELECT hash, extension, cid, cardinality(blocks), added FROM " + EXT_RESOURCE_TABLE + " WHERE hash = ?", new ResultSetExtractor<ResourceDTO>() {

            @Override
            public ResourceDTO extractData(ResultSet rs) throws SQLException, DataAccessException {
                if (rs.next()) {
                    ResourceDTO imageDTO = new ResourceDTO();
                    imageDTO.setHash(SecUtils.hexify(rs.getBytes(1)));
                    imageDTO.setExtension(rs.getString(2));
                    imageDTO.setCid(rs.getString(3));
                    imageDTO.setActive(rs.getInt(4) > 0);
                    imageDTO.setAdded(rs.getTimestamp(5));
                    return imageDTO;
                }
                return null;
            }
        }, new Object[] { SecUtils.getHashBytes(imageDTO.getHash()) });
    }

    public List<ResourceDTO> getResources(boolean active, int addedMoreThanSecondsAgo) {
        String isActiveSql = active ? "(blocks <> '{}' AND blocks is not null)" : "(blocks = '{}' OR blocks is null)";
        return jdbcTemplate.query("SELECT cid, hash, extension FROM " + EXT_RESOURCE_TABLE + " WHERE " + isActiveSql + " AND added < ?", new ResultSetExtractor<List<ResourceDTO>>() {

            @Override
            public List<ResourceDTO> extractData(ResultSet rs) throws SQLException, DataAccessException {
                List<ResourceDTO> resources = new LinkedList<>();
                while (rs.next()) {
                    ResourceDTO imageDTO = new ResourceDTO();
                    imageDTO.setCid(rs.getString(1));
                    imageDTO.setHash(SecUtils.hexify(rs.getBytes(2)));
                    imageDTO.setExtension(rs.getString(3));
                    resources.add(imageDTO);
                }
                return resources;
            }
        }, DateUtils.addSeconds(new Date(), -addedMoreThanSecondsAgo));
    }

    public void removeResource(ResourceDTO resDTO) {
        jdbcTemplate.update("DELETE FROM " + EXT_RESOURCE_TABLE + " WHERE hash = ?", new Object[] { SecUtils.getHashBytes(resDTO.getHash()) });
    }

    public void updateResourceBlock(ResourceDTO imageDTO, OpBlock block) {
        jdbcTemplate.update("INSERT INTO " + EXT_RESOURCE_TABLE + " (hash, extension, cid, added, blocks) VALUES (?, ?, ?, ?, array[?]) " + "ON CONFLICT (hash) DO UPDATE SET blocks = ARRAY(SELECT DISTINCT UNNEST(" + EXT_RESOURCE_TABLE + ".blocks || EXCLUDED.blocks))", SecUtils.getHashBytes(imageDTO.getHash()), imageDTO.getExtension(), imageDTO.getCid(), imageDTO.getAdded(), SecUtils.getHashBytes(block.getRawHash()));
    }

    public Long getAmountResourcesInDB() {
        return jdbcTemplate.query("SELECT COUNT(*) FROM " + EXT_RESOURCE_TABLE, new ResultSetExtractor<Long>() {

            @Override
            public Long extractData(ResultSet rs) throws SQLException, DataAccessException {
                if (rs.next()) {
                    return rs.getLong(1);
                }
                return null;
            }
        });
    }

    public boolean validateExistingOperation(OpOperation op) {
        String js = formatter.opToJson(op);
        OpOperation existingOperation = getOperationByHash(op.getHash());
        if (existingOperation != null && !js.equals(formatter.opToJson(existingOperation))) {
            throw new IllegalArgumentException(String.format("Operation is duplicated with '%s' hash but different content: \n'%s'\n'%s'", op.getHash(), formatter.opToJson(existingOperation).replace("\n", ""), js.replace("\n", "")));
        }
        return existingOperation != null;
    }

    public void insertOperation(OpOperation op) {
        txTemplate.execute(new TransactionCallback<OpOperation>() {

            @Override
            public OpOperation doInTransaction(TransactionStatus status) {
                PGobject pGobject = new PGobject();
                pGobject.setType("jsonb");
                String js = formatter.opToJson(op);
                String type = op.getType();
                try {
                    pGobject.setValue(js);
                } catch (SQLException e) {
                    throw new IllegalArgumentException(e);
                }
                byte[] bhash = SecUtils.getHashBytes(op.getHash());
                jdbcTemplate.update("INSERT INTO " + OPERATIONS_TABLE + "(hash, type, content) VALUES (?, ?, ?)", bhash, type, pGobject);
                return op;
            }
        });
    }

    public OpOperation getOperationByHash(String hash) {
        final byte[] bhash = SecUtils.getHashBytes(hash);
        OpOperation[] res = new OpOperation[1];
        jdbcTemplate.query("SELECT content from " + OPERATIONS_TABLE + " where hash = ?", new Object[] { bhash }, new RowCallbackHandler() {

            @Override
            public void processRow(ResultSet rs) throws SQLException {
                res[0] = formatter.parseOperation(rs.getString(1));
            }
        });
        return res[0];
    }

    public String getSetting(String key) {
        return dbSchema.getSetting(jdbcTemplate, key);
    }

    public Map<String, Map<String, OpIndexColumn>> getIndices() {
        return dbSchema.getIndexes();
    }
}

19 Source : JdbcTemplateStorageAccessor.java
with Apache License 2.0
from lukas-krecan

/**
 * Spring JdbcTemplate based implementation usable in JTA environment
 */
clreplaced JdbcTemplateStorageAccessor extends AbstractStorageAccessor {

    private final NamedParameterJdbcTemplate jdbcTemplate;

    private final TransactionTemplate transactionTemplate;

    private final Configuration configuration;

    private SqlStatementsSource sqlStatementsSource;

    JdbcTemplateStorageAccessor(@NonNull Configuration configuration) {
        requireNonNull(configuration, "configuration can not be null");
        this.jdbcTemplate = new NamedParameterJdbcTemplate(configuration.getJdbcTemplate());
        this.configuration = configuration;
        PlatformTransactionManager transactionManager = configuration.getTransactionManager() != null ? configuration.getTransactionManager() : new DataSourceTransactionManager(configuration.getJdbcTemplate().getDataSource());
        this.transactionTemplate = new TransactionTemplate(transactionManager);
        this.transactionTemplate.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRES_NEW);
    }

    @Override
    public boolean insertRecord(@NonNull LockConfiguration lockConfiguration) {
        try {
            String sql = sqlStatementsSource().getInsertStatement();
            return transactionTemplate.execute(status -> {
                Map<String, Object> params = params(lockConfiguration);
                int insertedRows = jdbcTemplate.update(sql, params);
                return insertedRows > 0;
            });
        } catch (DuplicateKeyException | CannotSerializeTransactionException e) {
            return false;
        } catch (DataIntegrityViolationException | BadSqlGrammarException | UncategorizedSQLException e) {
            logger.error("Unexpected exception", e);
            return false;
        }
    }

    @Override
    public boolean updateRecord(@NonNull LockConfiguration lockConfiguration) {
        String sql = sqlStatementsSource().getUpdateStatement();
        try {
            return transactionTemplate.execute(status -> {
                int updatedRows = jdbcTemplate.update(sql, params(lockConfiguration));
                return updatedRows > 0;
            });
        } catch (CannotSerializeTransactionException e) {
            return false;
        } catch (DataIntegrityViolationException e) {
            logger.error("Unexpected exception", e);
            return false;
        }
    }

    @Override
    public boolean extend(@NonNull LockConfiguration lockConfiguration) {
        String sql = sqlStatementsSource().getExtendStatement();
        logger.debug("Extending lock={} until={}", lockConfiguration.getName(), lockConfiguration.getLockAtMostUntil());
        return transactionTemplate.execute(status -> {
            int updatedRows = jdbcTemplate.update(sql, params(lockConfiguration));
            return updatedRows > 0;
        });
    }

    @Override
    public void unlock(@NonNull LockConfiguration lockConfiguration) {
        String sql = sqlStatementsSource().getUnlockStatement();
        transactionTemplate.execute(new TransactionCallbackWithoutResult() {

            @Override
            protected void doInTransactionWithoutResult(@NonNull TransactionStatus status) {
                jdbcTemplate.update(sql, params(lockConfiguration));
            }
        });
    }

    @NonNull
    private Map<String, Object> params(@NonNull LockConfiguration lockConfiguration) {
        return sqlStatementsSource().params(lockConfiguration);
    }

    private SqlStatementsSource sqlStatementsSource() {
        synchronized (configuration) {
            if (sqlStatementsSource == null) {
                sqlStatementsSource = SqlStatementsSource.create(configuration);
            }
            return sqlStatementsSource;
        }
    }
}

19 Source : ProgramaticUserService.java
with Apache License 2.0
from linnykoleh

@Service("programaticUserService")
public clreplaced ProgramaticUserService implements UserService {

    private UserRepo userRepo;

    private TransactionTemplate txTemplate;

    @Autowired
    public ProgramaticUserService(UserRepo userRepo, PlatformTransactionManager txManager) {
        this.userRepo = userRepo;
        this.txTemplate = new TransactionTemplate(txManager);
    }

    @Override
    public User findById(Long id) {
        return txTemplate.execute(status -> {
            User user = null;
            try {
                user = userRepo.findById(id);
            } catch (Exception e) {
                status.setRollbackOnly();
            }
            return user;
        });
    }

    @Override
    public void htmlAllByNameAll(String name) {
        userRepo.htmlAllByName(name);
    }

    @Override
    public int countUsers() {
        return userRepo.countUsers();
    }

    @Override
    public int updatePreplacedword(Long userId, String newPreplaced) throws MailSendingException {
        return txTemplate.execute(status -> {
            try {
                int result = userRepo.updatePreplacedword(userId, newPreplaced);
                User user = userRepo.findById(userId);
                String email = user.getEmail();
                sendEmail(email);
                return result;
            } catch (MailSendingException e) {
                status.setRollbackOnly();
            }
            return 0;
        });
    }

    private void sendEmail(String email) throws MailSendingException {
        if (true) {
            throw new MailSendingException("Confirmation email for preplacedword could not be sent. Preplacedword was not send.");
        }
    }
}

19 Source : UserService.java
with Apache License 2.0
from LinkedBear

@Service
public clreplaced UserService {

    @Autowired
    TransactionTemplate transactionTemplate;

    @Autowired
    UserDao userDao;

    public void saveAndQuery() {
        User user = new User();
        user.setName("阿巴阿巴");
        user.setTel("123654789");
        // userDao.save(user);
        // 
        // int i = 1 / 0;
        // 
        // List<User> userList = userDao.findAll();
        // System.out.println(userList);
        // transactionTemplate.execute(status -> {
        // userDao.save(user);
        // 
        // int i = 1 / 0;
        // 
        // List<User> userList = userDao.findAll();
        // System.out.println(userList);
        // return null;
        // });
        transactionTemplate.execute(new TransactionCallbackWithoutResult() {

            @Override
            protected void doInTransactionWithoutResult(TransactionStatus status) {
                userDao.save(user);
                int i = 1 / 0;
                List<User> userList = userDao.findAll();
                System.out.println(userList);
            }
        });
    }
}

19 Source : LeafSegmentServiceTest.java
with Apache License 2.0
from linhuaichuan

/**
 * @author sunff
 */
@RunWith(SpringJUnit4ClreplacedRunner.clreplaced)
@ContextConfiguration(locations = { "file:src/test/resources/idleaf/app-leaf.xml" })
public clreplaced LeafSegmentServiceTest {

    @Autowired
    @Qualifier("segmentService")
    private SegmentServiceImpl segmentServiceImpl;

    @Autowired
    private JdbcTemplate jdbcTemplate;

    private BlockingQueue<Long> queue = new LinkedBlockingQueue<Long>(1000);

    @Test
    public void synGetId() {
        int i = 0;
        while (true) {
            System.out.println(++i + " :" + segmentServiceImpl.getId());
        }
    }

    @Autowired
    private TransactionTemplate transactionTemplate;

    public void batchInsert() {
        List<Long> list = new ArrayList<Long>(1000);
        for (Long i = 0L; i < 1000L; i++) {
            list.add(i);
        }
        try {
            TimeUnit.SECONDS.sleep(3);
        } catch (InterruptedException e1) {
            // TODO Auto-generated catch block
            e1.printStackTrace();
        }
        try {
            final List<Long> insertedList = list;
            transactionTemplate.execute(new TransactionCallback<Integer>() {

                @Override
                public Integer doInTransaction(TransactionStatus status) {
                    jdbcTemplate.batchUpdate("insert into id_test(p_id) values(?)", new BatchPreparedStatementSetter() {

                        @Override
                        public void setValues(PreparedStatement ps, int i) throws SQLException {
                            Long insertedId = insertedList.get(i);
                            ps.setLong(1, insertedId);
                        }

                        @Override
                        public int getBatchSize() {
                            return insertedList.size();
                        }
                    });
                    return insertedList.size();
                }
            });
            System.out.println("oooolk");
        } catch (Exception e) {
        }
    }

    public void getId() {
        new Thread() {

            @Override
            public void run() {
                List<Long> list = new ArrayList<Long>(10000);
                while (true) {
                    try {
                        Long id = queue.take();
                        // jdbcTemplate.update("insert into id_test(p_id) values(?)",
                        // l);
                        // System.out.println("id=" + id);
                        if (list.size() == 10000) {
                            final List<Long> insertedList = list;
                            transactionTemplate.execute(new TransactionCallback<Integer>() {

                                @Override
                                public Integer doInTransaction(TransactionStatus status) {
                                    jdbcTemplate.batchUpdate("insert into id_test(p_id) values(?)", new BatchPreparedStatementSetter() {

                                        @Override
                                        public void setValues(PreparedStatement ps, int i) throws SQLException {
                                            Long insertedId = insertedList.get(i);
                                            ps.setLong(1, insertedId);
                                        }

                                        @Override
                                        public int getBatchSize() {
                                            return insertedList.size();
                                        }
                                    });
                                    return insertedList.size();
                                }
                            });
                            list.clear();
                        } else {
                            list.add(id);
                        }
                    } catch (InterruptedException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                }
            }
        }.start();
        int count = 0;
        while (true) {
            // System.out.println(idLeafService.getId());
            try {
                queue.put(segmentServiceImpl.getId());
                count++;
                if (count % 1000 == 0) {
                    System.out.println("current count no is " + count);
                }
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
    }
}

19 Source : ServiceTemplateImpl.java
with Apache License 2.0
from leon66666

public clreplaced ServiceTemplateImpl implements ServiceTemplate {

    private static final ILogger logger = ILoggerFactory.getLogger(ServiceTemplateImpl.clreplaced);

    @Autowired
    protected TransactionTemplate transactionTemplate;

    public CallbackResult execute(ServiceCallback action, Object domain) {
        return execute(action, domain, null);
    }

    public CallbackResult executeWithoutTransaction(ServiceCallback action, Object domain) {
        return executeWithoutTransaction(action, domain, null);
    }

    public CallbackResult execute(final ServiceCallback action, Object domain, ServiceListener listener) {
        if (logger.isDebugEnabled()) {
            logger.debug("进入模板方法开始处理");
        }
        if (listener == null) {
            listener = new AbstractServiceListener();
        }
        final ServiceListener flistener = listener;
        CallbackResult result = null;
        try {
            flistener.beforeCheck();
            result = action.executeCheck();
            flistener.afterCheck();
            if (result.isSuccess()) {
                flistener.beforeExecute();
                result = (CallbackResult) this.transactionTemplate.execute(new TransactionCallback() {

                    public Object doInTransaction(TransactionStatus status) {
                        CallbackResult iNresult = action.executeAction();
                        if (null == iNresult) {
                            throw new ServiceException(CallbackResult.FAILURE);
                        }
                        flistener.templateExtensionInTransaction(iNresult);
                        if (iNresult.isFailure()) {
                            status.setRollbackOnly();
                            return iNresult;
                        }
                        return iNresult;
                    }
                });
                flistener.afterExecute();
                if (result.isSuccess()) {
                    flistener.templateExtensionAfterTransactionSuccess(result);
                }
                if (result.isFailure()) {
                    flistener.templateExtensionAfterTransactionFailure(result);
                }
            }
        } catch (ServiceException e) {
            e.printStackTrace();
            result = CallbackResult.failure(e.getErrorCode(), e, e.getParameters());
            flistener.onException(e);
        } catch (CommonRuntimeException e) {
            e.printStackTrace();
            result = CallbackResult.failure(e.getErrorCode(), e, e.getParameters());
            flistener.onException(e);
        } catch (Throwable e) {
            e.printStackTrace();
            result = CallbackResult.failure(CallbackResult.FAILURE, e);
            flistener.onException(e);
        }
        if (logger.isDebugEnabled()) {
            logger.debug("模板方法处理结束");
        }
        return result;
    }

    public CallbackResult executeWithoutTransaction(ServiceCallback action, Object domain, ServiceListener listener) {
        if (logger.isDebugEnabled()) {
            logger.debug("进入模板方法开始处理");
        }
        if (listener == null) {
            listener = new AbstractServiceListener();
        }
        ServiceListener flistener = listener;
        CallbackResult result = null;
        try {
            flistener.beforeCheck();
            result = action.executeCheck();
            flistener.afterCheck();
            if (result.isSuccess()) {
                flistener.beforeExecute();
                result = action.executeAction();
                flistener.afterExecute();
                if (null == result) {
                    throw new ServiceException(CallbackResult.FAILURE_NO_ROLLBACK);
                }
                flistener.templateExtensionAfterExecuteSuccess(result);
            }
            if (result.isFailure())
                flistener.templateExtensionAfterExecuteFailure(result);
        } catch (ServiceException e) {
            e.printStackTrace();
            result = CallbackResult.failure(e.getErrorCode(), e, e.getParameters());
            flistener.onException(e);
        } catch (CommonRuntimeException e) {
            e.printStackTrace();
            result = CallbackResult.failure(e.getErrorCode(), e, e.getParameters());
            flistener.onException(e);
        } catch (Throwable e) {
            e.printStackTrace();
            result = CallbackResult.failure(CallbackResult.FAILURE, e);
            flistener.onException(e);
        }
        if (logger.isDebugEnabled()) {
            logger.debug("模板方法处理结束");
        }
        return result;
    }

    public void setTransactionTemplate(TransactionTemplate transactionTemplate) {
        this.transactionTemplate = transactionTemplate;
    }
}

19 Source : HttpServerScheduleProtocol.java
with Apache License 2.0
from learningtcc

/**
 * initDTSSchedule
 */
@PostConstruct
public void initDTSSchedule() {
    JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);
    TransactionTemplate transactionTemplate = new TransactionTemplate(new DataSourceTransactionManager(dataSource));
    transactionTemplate.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRES_NEW);
    localDTSSchedule = new LocalDTSSchedule(jdbcTemplate, transactionTemplate);
}

19 Source : LocalJobTrackerDelegate.java
with Apache License 2.0
from learningtcc

private void initLocalDTSSchedule() {
    JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);
    TransactionTemplate transactionTemplate = new TransactionTemplate(new DataSourceTransactionManager(dataSource));
    transactionTemplate.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRES_NEW);
    localDTSSchedule = new LocalDTSSchedule(jdbcTemplate, transactionTemplate);
}

19 Source : DTS.java
with Apache License 2.0
from learningtcc

/**
 * @author ligaofeng 2016年12月16日 上午11:07:30
 */
@Slf4j
public clreplaced DTS implements IDTS {

    protected final JdbcTemplate jdbcTemplate;

    protected final TransactionTemplate transactionTemplate;

    public DTS(JdbcTemplate jdbcTemplate, TransactionTemplate transactionTemplate) {
        this.jdbcTemplate = jdbcTemplate;
        this.transactionTemplate = transactionTemplate;
    }

    @Override
    public ResultBase<List<ActionEnreplacedy>> getActionEnreplacedies(String activityId) {
        ResultBase<List<ActionEnreplacedy>> actionListBase = new ResultBase<List<ActionEnreplacedy>>();
        List<ActionEnreplacedy> actionEnreplacedyList = Lists.newArrayList();
        actionListBase.setValue(actionEnreplacedyList);
        try {
            Object[] params = new Object[] { activityId };
            List<DtsActionDO> actionList = jdbcTemplate.query(ActionSqlConstance.select_dts_action_by_activity_id, params, new DtsActionRowMapper());
            actionListBase.setDtsResultCode(DTSResultCode.SUCCESS);
            for (DtsActionDO actionDO : actionList) {
                actionEnreplacedyList.add(ActionHelper.toActionEnreplacedy(actionDO));
            }
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            actionListBase.setDtsResultCode(DTSResultCode.FAIL);
            actionListBase.setMessage("数据库查询出错");
        }
        return actionListBase;
    }
}

19 Source : SpringTransactionRunner.java
with Apache License 2.0
from katharsis-project

@Override
public <T> T doInTransaction(final Callable<T> callable) {
    TransactionTemplate template = new TransactionTemplate(platformTransactionManager);
    return template.execute(new TransactionCallback<T>() {

        @Override
        public T doInTransaction(TransactionStatus status) {
            try {
                return callable.call();
            } catch (RuntimeException e) {
                throw e;
            } catch (Exception e) {
                throw new IllegalStateException(e);
            }
        }
    });
}

19 Source : SpringTransactionRunner.java
with Apache License 2.0
from katharsis-project

@Override
public <T> T doInTransaction(final Callable<T> callable) {
    TransactionTemplate template = new TransactionTemplate(platformTransactionManager);
    return template.execute(new TransactionCallback<T>() {

        @Override
        public T doInTransaction(TransactionStatus status) {
            try {
                return callable.call();
            } catch (RuntimeException e) {
                throw e;
            } catch (Exception e) {
                throw new RuntimeException(e);
            }
        }
    });
}

19 Source : AddressServiceImpl.java
with Apache License 2.0
from jufeng98

/**
 * @author yudong
 * @date 2020/5/15
 */
@Service
public clreplaced AddressServiceImpl implements AddressService {

    @Autowired
    private DataSource dataSource;

    @Autowired
    private JdbcTemplate jdbcTemplate;

    @Autowired
    private TransactionTemplate transactionTemplate;

    @Autowired
    private AddressHelper addressHelper;

    @SneakyThrows
    @Override
    public String transactionOriginalResearch() {
        try (Connection conn = dataSource.getConnection()) {
            conn.setAutoCommit(false);
            short countryId;
            PreparedStatement preparedStatement = null;
            ResultSet resultSet = null;
            try {
                // 其他业务逻辑处理
                // ......
                preparedStatement = conn.prepareStatement("insert into country(country) values (?)", Statement.RETURN_GENERATED_KEYS);
                preparedStatement.setString(1, "中国");
                preparedStatement.executeUpdate();
                resultSet = preparedStatement.getGeneratedKeys();
                resultSet.next();
                countryId = resultSet.getShort(1);
                conn.commit();
            } catch (Exception e) {
                conn.rollback();
                throw new RuntimeException(e);
            } finally {
                if (preparedStatement != null) {
                    preparedStatement.close();
                }
                if (resultSet != null) {
                    resultSet.close();
                }
            }
            short cityId;
            try {
                // 其他业务逻辑处理
                // ......
                preparedStatement = conn.prepareStatement("insert into city(city, country_id) values (?,?)", Statement.RETURN_GENERATED_KEYS);
                preparedStatement.setString(1, "北京");
                preparedStatement.setShort(2, countryId);
                preparedStatement.executeUpdate();
                resultSet = preparedStatement.getGeneratedKeys();
                resultSet.next();
                cityId = resultSet.getShort(1);
                conn.commit();
            } catch (Exception e) {
                conn.rollback();
                throw new RuntimeException(e);
            } finally {
                if (preparedStatement != null) {
                    preparedStatement.close();
                }
                if (resultSet != null) {
                    resultSet.close();
                }
            }
            // country表和city表均保存成功,此处设置个Savepoint(保存点)
            Savepoint savepointCity = conn.setSavepoint("city");
            int affect;
            try {
                // 其他业务逻辑处理
                // ......
                preparedStatement = conn.prepareStatement("insert into category(name) values (?)");
                preparedStatement.setString(1, "分类名称");
                affect = preparedStatement.executeUpdate();
                if (true) {
                    throw new RuntimeException("模拟抛出异常");
                }
                conn.commit();
            } catch (Exception e) {
                conn.rollback(savepointCity);
                throw new RuntimeException(e);
            } finally {
                if (preparedStatement != null) {
                    preparedStatement.close();
                }
            }
            return countryId + " " + cityId + " " + affect;
        }
    }

    /**
     * 声明式事务
     */
    @Override
    @Transactional(timeout = 6000, rollbackFor = Exception.clreplaced)
    public String transactionResearch() {
        String res = addressHelper.save();
        // 其他业务逻辑处理
        // ......
        int affect = jdbcTemplate.update("insert into category(name) values (?)", "分类名称");
        if (true) {
            throw new RuntimeException("模拟抛出异常");
        }
        return res + " " + affect;
    }

    /**
     * 编程式事务
     */
    @Override
    public String transactionResearch1() {
        return transactionTemplate.execute(status -> {
            // 其他业务逻辑处理
            // ......
            GeneratedKeyHolder keyHolder = new GeneratedKeyHolder();
            jdbcTemplate.update(con -> {
                PreparedStatement preparedStatement = con.prepareStatement("insert into country(country) values (?)", Statement.RETURN_GENERATED_KEYS);
                preparedStatement.setString(1, "中国");
                return preparedStatement;
            }, keyHolder);
            short countryId = keyHolder.getKey().shortValue();
            // 其他业务逻辑处理
            // ......
            GeneratedKeyHolder keyHolder1 = new GeneratedKeyHolder();
            jdbcTemplate.update(con -> {
                PreparedStatement preparedStatement = con.prepareStatement("insert into city(city,country_id) values (?,?)", Statement.RETURN_GENERATED_KEYS);
                preparedStatement.setString(1, "北京");
                preparedStatement.setInt(2, countryId);
                return preparedStatement;
            }, keyHolder1);
            short cityId = keyHolder1.getKey().shortValue();
            Object savepointCity = status.createSavepoint();
            int affect = 0;
            try {
                // 其他业务逻辑处理
                // ......
                affect = jdbcTemplate.update("insert into category(name) values (?)", "分类名称");
                if (true) {
                    throw new RuntimeException("模拟抛出异常");
                }
            } catch (Exception e) {
                status.rollbackToSavepoint(savepointCity);
            }
            return countryId + " " + cityId + " " + affect;
        });
    }
}

19 Source : TxTemplatedUserDao.java
with Apache License 2.0
from Illusionist80

/**
 * This clreplaced demonstrates how to use transaction template to programatically
 *  handle transactions.
 */
public clreplaced TxTemplatedUserDao implements IUserDao {

    private JdbcTemplate jdbcTemplate;

    private TransactionTemplate transactionTemplate;

    public void setTransactionTemplate(TransactionTemplate transactionTemplate) {
        this.transactionTemplate = transactionTemplate;
        // set transaction propagation behaviour like this
        this.transactionTemplate.setPropagationBehavior(TransactionTemplate.PROPAGATION_REQUIRES_NEW);
    }

    public void setJdbcTemplate(JdbcTemplate jdbcTemplate) {
        this.jdbcTemplate = jdbcTemplate;
    }

    public void deleteUser(final int uid) {
        // use TransactionCallbackWithoutResult handler if ur query doesnt result anything
        transactionTemplate.execute(new TransactionCallbackWithoutResult() {

            protected void doInTransactionWithoutResult(TransactionStatus paramTransactionStatus) {
                try {
                    String delQuery = "delete from users where id = ?";
                    jdbcTemplate.update(delQuery, new Object[] { uid });
                } catch (Exception e) {
                    // use this to rollback exception in case of exception
                    paramTransactionStatus.setRollbackOnly();
                }
            }
        });
    }

    public int insertUser(final User user) {
        // use TransactionCallback handler if some result is returned
        return transactionTemplate.execute(new TransactionCallback<Integer>() {

            public Integer doInTransaction(TransactionStatus paramTransactionStatus) {
                String inserQuery = "insert into users (username, preplacedword, enabled , id) values (?, ?, ?, ?) ";
                Object[] params = new Object[] { user.getUserName(), user.getPreplacedword(), user.isEnabled(), user.getId() };
                int[] types = new int[] { Types.VARCHAR, Types.VARCHAR, Types.BIT, Types.INTEGER };
                return jdbcTemplate.update(inserQuery, params, types);
            }
        });
    }

    public User selectUser(int uid) {
        // TODO Auto-generated method stub
        return null;
    }

    public int updateUser(User user) {
        // TODO Auto-generated method stub
        return 0;
    }
}

19 Source : TxTemplatedUserDao.java
with Apache License 2.0
from Illusionist80

public void setTransactionTemplate(TransactionTemplate transactionTemplate) {
    this.transactionTemplate = transactionTemplate;
    // set transaction propagation behaviour like this
    this.transactionTemplate.setPropagationBehavior(TransactionTemplate.PROPAGATION_REQUIRES_NEW);
}

19 Source : ParameterDaoImpl.java
with Apache License 2.0
from igloo-project

public clreplaced ParameterDaoImpl extends GenericEnreplacedyDaoImpl<Long, Parameter> implements IMutablePropertyDao {

    private TransactionTemplate readOnlyTransactionTemplate;

    private TransactionTemplate writeTransactionTemplate;

    private Parameter getByName(String name) {
        return super.getByNaturalId(name);
    }

    @Override
    public String getInTransaction(final String key) {
        return readOnlyTransactionTemplate.execute(new TransactionCallback<String>() {

            @Override
            public String doInTransaction(TransactionStatus status) {
                return get(key);
            }
        });
    }

    @Override
    public void setInTransaction(final String key, final String value) throws ServiceException, SecurityServiceException {
        writeTransactionTemplate.execute(new TransactionCallbackWithoutResult() {

            @Override
            protected void doInTransactionWithoutResult(TransactionStatus status) {
                try {
                    set(key, value);
                } catch (RuntimeException | ServiceException | SecurityServiceException e) {
                    throw new IllegalStateException(String.format("Error while updating property '%1s'.", key), e);
                }
            }
        });
    }

    @Override
    public void cleanInTransaction() {
        writeTransactionTemplate.execute(new TransactionCallbackWithoutResult() {

            @Override
            protected void doInTransactionWithoutResult(TransactionStatus status) {
                clean();
            }
        });
    }

    @Autowired
    public void setPlatformTransactionManager(PlatformTransactionManager transactionManager) {
        DefaultTransactionAttribute readOnlyTransactionAttribute = new DefaultTransactionAttribute(TransactionAttribute.PROPAGATION_REQUIRED);
        readOnlyTransactionAttribute.setReadOnly(true);
        readOnlyTransactionTemplate = new TransactionTemplate(transactionManager, readOnlyTransactionAttribute);
        DefaultTransactionAttribute writeTransactionAttribute = new DefaultTransactionAttribute(TransactionAttribute.PROPAGATION_REQUIRED);
        writeTransactionAttribute.setReadOnly(false);
        writeTransactionTemplate = new TransactionTemplate(transactionManager, writeTransactionAttribute);
    }

    private String get(String key) {
        Parameter parameter = getByName(key);
        if (parameter == null) {
            return null;
        }
        return parameter.getStringValue();
    }

    private void set(String key, String value) throws ServiceException, SecurityServiceException {
        Parameter parameter = getByName(key);
        if (parameter != null) {
            parameter.setStringValue(value);
            update(parameter);
        } else {
            save(new Parameter(key, value));
        }
    }

    private void clean() {
        for (Parameter parameter : list()) {
            delete(parameter);
        }
    }
}

19 Source : ExternalLinkCheckByDomainTask.java
with Apache License 2.0
from igloo-project

@Override
public Void call() throws Exception {
    TransactionTemplate template = new TransactionTemplate(transactionManager);
    return template.execute(new TransactionCallback<Void>() {

        @Override
        public Void doInTransaction(TransactionStatus status) {
            Session session = enreplacedyManagerUtils.getEnreplacedyManager().unwrap(Session.clreplaced);
            session.setHibernateFlushMode(FlushMode.COMMIT);
            int count = 0;
            for (Map.Entry<io.mola.galimatias.URL, Collection<Long>> urlToIdsEntry : urlToIdsMap.entrySet()) {
                // We flush the session to avoid a memory overhead if there is a huge amount of links within the same domain
                if (count >= SESSION_LIMIT) {
                    session.flush();
                    session.clear();
                    count = 0;
                }
                io.mola.galimatias.URL url = urlToIdsEntry.getKey();
                try {
                    Collection<ExternalLinkWrapper> links = externalLinkWrapperService.listByIds(urlToIdsEntry.getValue());
                    linkCheckerService.checkLinksWithSameUrl(url, links);
                    count += links.size();
                } catch (RuntimeException | ServiceException | SecurityServiceException e) {
                    LOGGER.error("An error occurred while checking links", e);
                }
            }
            return null;
        }
    });
}

19 Source : TransactionScopeIndependantRunnerServiceImpl.java
with Apache License 2.0
from igloo-project

@Service
public clreplaced TransactionScopeIndependantRunnerServiceImpl implements ITransactionScopeIndependantRunnerService {

    private TransactionTemplate readOnlyTransactionTemplate;

    private TransactionTemplate writeTransactionTemplate;

    @Autowired
    public void setPlatformTransactionManager(PlatformTransactionManager transactionManager) {
        DefaultTransactionAttribute readOnlyTransactionAttribute = new DefaultTransactionAttribute(TransactionAttribute.PROPAGATION_REQUIRES_NEW);
        readOnlyTransactionAttribute.setReadOnly(true);
        readOnlyTransactionTemplate = new TransactionTemplate(transactionManager, readOnlyTransactionAttribute);
        DefaultTransactionAttribute writeTransactionAttribute = new DefaultTransactionAttribute(TransactionAttribute.PROPAGATION_REQUIRES_NEW);
        writeTransactionAttribute.setReadOnly(false);
        writeTransactionTemplate = new TransactionTemplate(transactionManager, writeTransactionAttribute);
    }

    @Override
    public <T> T run(final Callable<T> callable) {
        return run(true, callable);
    }

    @Override
    public <T> T run(boolean readOnly, final Callable<T> callable) {
        TransactionTemplate transactionTemplate = readOnly ? readOnlyTransactionTemplate : writeTransactionTemplate;
        return transactionTemplate.execute(new TransactionCallback<T>() {

            @Override
            public T doInTransaction(TransactionStatus transactionStatus) {
                try {
                    return callable.call();
                } catch (Exception e) {
                    if (e instanceof InterruptedException) {
                        Thread.currentThread().interrupt();
                    }
                    throw new IllegalStateException(String.format("Erreur durant l'execution du callable %s", callable), e);
                }
            }
        });
    }
}

19 Source : TransactionScopeIndependantRunnerServiceImpl.java
with Apache License 2.0
from igloo-project

@Override
public <T> T run(boolean readOnly, final Callable<T> callable) {
    TransactionTemplate transactionTemplate = readOnly ? readOnlyTransactionTemplate : writeTransactionTemplate;
    return transactionTemplate.execute(new TransactionCallback<T>() {

        @Override
        public T doInTransaction(TransactionStatus transactionStatus) {
            try {
                return callable.call();
            } catch (Exception e) {
                if (e instanceof InterruptedException) {
                    Thread.currentThread().interrupt();
                }
                throw new IllegalStateException(String.format("Erreur durant l'execution du callable %s", callable), e);
            }
        }
    });
}

19 Source : JndiRoutingDataSourceTemplate.java
with Apache License 2.0
from i-novus-llc

/**
 * User: iryabov
 * Date: 27.08.13
 * Time: 13:52
 */
public clreplaced JndiRoutingDataSourceTemplate {

    private TransactionTemplate transactionTemplate;

    public <T> T execute(String jndiName, RoutingDataSourceCallback<T> action) {
        JndiContextHolder.setJndiContext(jndiName);
        try {
            return action.onRouting();
        } finally {
            JndiContextHolder.clearJndiContext();
        }
    }

    public <T> T execute(String jndiName, final TransactionCallback<T> action) {
        if (transactionTemplate == null)
            throw new IllegalStateException("transactionTemplate is null");
        return execute(jndiName, () -> {
            return transactionTemplate.execute(action);
        });
    }

    public void setTransactionTemplate(TransactionTemplate transactionTemplate) {
        this.transactionTemplate = transactionTemplate;
    }
}

19 Source : TransactionContextStartupRoutine.java
with BSD 3-Clause "New" or "Revised" License
from dhis2

/**
 * @author Lars Helge Overland
 */
public abstract clreplaced TransactionContextStartupRoutine extends AbstractStartupRoutine {

    @Autowired
    private TransactionTemplate transactionTemplate;

    /**
     * Work performed in this method will run inside a transaction context.
     */
    public abstract void executeInTransaction();

    @Override
    public final void execute() {
        transactionTemplate.execute(new TransactionCallback<Object>() {

            @Override
            public Object doInTransaction(TransactionStatus status) {
                executeInTransaction();
                return null;
            }
        });
    }
}

19 Source : SpringTransactionRunner.java
with Apache License 2.0
from crnk-project

@Override
public <T> T doInTransaction(final Callable<T> callable) {
    DefaultTransactionDefinition definition = new DefaultTransactionDefinition();
    definition.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED);
    TransactionTemplate template = new TransactionTemplate(platformTransactionManager, definition);
    try {
        return template.execute(new TransactionCallback<T>() {

            @Override
            public T doInTransaction(TransactionStatus status) {
                try {
                    T result = callable.call();
                    if (status.isRollbackOnly()) {
                        // TransactionTemplate does not properly deal with Rollback exceptions
                        // an exception is required, otherwise it will attempt to commit again
                        throw new RollbackOnlyException(result);
                    }
                    return result;
                } catch (RuntimeException e) {
                    throw e;
                } catch (Exception e) {
                    throw new IllegalStateException(e);
                }
            }
        });
    } catch (RollbackOnlyException e) {
        return (T) e.getResult();
    }
}

19 Source : InventoryService.java
with Apache License 2.0
from AnghelLeonard

@Service
public clreplaced InventoryService implements Runnable {

    private final InventoryRepository inventoryRepository;

    private final TransactionTemplate transactionTemplate;

    public InventoryService(InventoryRepository inventoryRepository, TransactionTemplate transactionTemplate) {
        this.inventoryRepository = inventoryRepository;
        this.transactionTemplate = transactionTemplate;
    }

    @Override
    @Retry(times = 10, on = OptimisticLockingFailureException.clreplaced)
    public void run() {
        transactionTemplate.execute(new TransactionCallbackWithoutResult() {

            @Override
            public void doInTransactionWithoutResult(TransactionStatus status) {
                Inventory inventory = inventoryRepository.findById(1L).orElseThrow();
                inventory.setQuanreplacedy(inventory.getQuanreplacedy() - 2);
            }
        });
    }
}

19 Source : BookstoreService.java
with Apache License 2.0
from AnghelLeonard

@Service
public clreplaced BookstoreService {

    private final TransactionTemplate template;

    private final BookRepository bookRepository;

    public BookstoreService(BookRepository bookRepository, TransactionTemplate template) {
        this.bookRepository = bookRepository;
        this.template = template;
    }

    public void fetchBooksViaTwoTransactions() {
        template.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRES_NEW);
        template.execute(new TransactionCallbackWithoutResult() {

            @Override
            protected void doInTransactionWithoutResult(TransactionStatus status) {
                List<Book> books = bookRepository.findTop3ByStatus(BookStatus.PENDING, Sort.by(Sort.Direction.ASC, "id"));
                template.execute(new TransactionCallbackWithoutResult() {

                    @Override
                    protected void doInTransactionWithoutResult(TransactionStatus status) {
                        List<Book> books = bookRepository.findTop3ByStatus(BookStatus.PENDING, Sort.by(Sort.Direction.ASC, "id"));
                        System.out.println("Second transaction: " + books);
                    }
                });
                System.out.println("First transaction: " + books);
            }
        });
        System.out.println("Done!");
    }
}

19 Source : LocalDataSourceServiceImpl.java
with Apache License 2.0
from alibaba

/**
 * local data source.
 *
 * @author Nacos
 */
public clreplaced LocalDataSourceServiceImpl implements DataSourceService {

    private final String jdbcDriverName = "org.apache.derby.jdbc.EmbeddedDriver";

    private final String userName = "nacos";

    private final String preplacedword = "nacos";

    private final String derbyBaseDir = "data" + File.separator + "derby-data";

    private final String derbyShutdownErrMsg = "Derby system shutdown.";

    private volatile JdbcTemplate jt;

    private volatile TransactionTemplate tjt;

    private boolean initialize = false;

    private boolean jdbcTemplateInit = false;

    private String healthStatus = "UP";

    @PostConstruct
    @Override
    public synchronized void init() throws Exception {
        if (!PropertyUtil.isUseExternalDB()) {
            if (!initialize) {
                LogUtil.DEFAULT_LOG.info("use local db service for init");
                final String jdbcUrl = "jdbc:derby:" + Paths.get(EnvUtil.getNacosHome(), derbyBaseDir).toString() + ";create=true";
                initialize(jdbcUrl);
                initialize = true;
            }
        }
    }

    @Override
    public synchronized void reload() {
        DataSource ds = jt.getDataSource();
        if (ds == null) {
            throw new RuntimeException("datasource is null");
        }
        try {
            execute(ds.getConnection(), "META-INF/schema.sql");
        } catch (Exception e) {
            if (LogUtil.DEFAULT_LOG.isErrorEnabled()) {
                LogUtil.DEFAULT_LOG.error(e.getMessage(), e);
            }
            throw new NacosRuntimeException(NacosException.SERVER_ERROR, "load schema.sql error.", e);
        }
    }

    public DataSource getDatasource() {
        return jt.getDataSource();
    }

    /**
     * Clean and reopen Derby.
     *
     * @throws Exception exception.
     */
    public void cleanAndReopenDerby() throws Exception {
        doDerbyClean();
        final String jdbcUrl = "jdbc:derby:" + Paths.get(EnvUtil.getNacosHome(), derbyBaseDir).toString() + ";create=true";
        initialize(jdbcUrl);
    }

    /**
     * Restore derby.
     *
     * @param jdbcUrl  jdbcUrl string value.
     * @param callable callable.
     * @throws Exception exception.
     */
    public void restoreDerby(String jdbcUrl, Callable<Void> callable) throws Exception {
        doDerbyClean();
        callable.call();
        initialize(jdbcUrl);
    }

    private void doDerbyClean() throws Exception {
        LogUtil.DEFAULT_LOG.warn("use local db service for reopenDerby");
        try {
            DriverManager.getConnection("jdbc:derby:;shutdown=true");
        } catch (Exception e) {
            // An error is thrown when the Derby shutdown is executed, which should be ignored
            if (!StringUtils.containsIgnoreCase(e.getMessage(), derbyShutdownErrMsg)) {
                throw e;
            }
        }
        DiskUtils.deleteDirectory(Paths.get(EnvUtil.getNacosHome(), derbyBaseDir).toString());
    }

    private synchronized void initialize(String jdbcUrl) {
        DataSourcePoolProperties poolProperties = DataSourcePoolProperties.build(EnvUtil.getEnvironment());
        poolProperties.setDriverClreplacedName(jdbcDriverName);
        poolProperties.setJdbcUrl(jdbcUrl);
        poolProperties.setUsername(userName);
        poolProperties.setPreplacedword(preplacedword);
        HikariDataSource ds = poolProperties.getDataSource();
        DataSourceTransactionManager tm = new DataSourceTransactionManager();
        tm.setDataSource(ds);
        if (jdbcTemplateInit) {
            jt.setDataSource(ds);
            tjt.setTransactionManager(tm);
        } else {
            jt = new JdbcTemplate();
            jt.setMaxRows(50000);
            jt.setQueryTimeout(5000);
            jt.setDataSource(ds);
            tjt = new TransactionTemplate(tm);
            tjt.setTimeout(5000);
            jdbcTemplateInit = true;
        }
        reload();
    }

    @Override
    public boolean checkMasterWritable() {
        return true;
    }

    @Override
    public JdbcTemplate getJdbcTemplate() {
        return jt;
    }

    @Override
    public TransactionTemplate getTransactionTemplate() {
        return tjt;
    }

    @Override
    public String getCurrentDbUrl() {
        return "jdbc:derby:" + EnvUtil.getNacosHome() + File.separator + derbyBaseDir + ";create=true";
    }

    @Override
    public String getHealth() {
        return healthStatus;
    }

    public void setHealthStatus(String healthStatus) {
        this.healthStatus = healthStatus;
    }

    /**
     * Load sql.
     *
     * @param sqlFile sql.
     * @return sqls.
     * @throws Exception Exception.
     */
    private List<String> loadSql(String sqlFile) throws Exception {
        List<String> sqlList = new ArrayList<String>();
        InputStream sqlFileIn = null;
        try {
            File file = new File(EnvUtil.getNacosHome() + File.separator + "conf" + File.separator + "schema.sql");
            if (StringUtils.isBlank(EnvUtil.getNacosHome()) || !file.exists()) {
                ClreplacedLoader clreplacedLoader = getClreplaced().getClreplacedLoader();
                URL url = clreplacedLoader.getResource(sqlFile);
                sqlFileIn = url.openStream();
            } else {
                sqlFileIn = new FileInputStream(file);
            }
            StringBuilder sqlSb = new StringBuilder();
            byte[] buff = new byte[1024];
            int byteRead = 0;
            while ((byteRead = sqlFileIn.read(buff)) != -1) {
                sqlSb.append(new String(buff, 0, byteRead, Constants.ENCODE));
            }
            String[] sqlArr = sqlSb.toString().split(";");
            for (int i = 0; i < sqlArr.length; i++) {
                String sql = sqlArr[i].replaceAll("--.*", "").trim();
                if (StringUtils.isNotEmpty(sql)) {
                    sqlList.add(sql);
                }
            }
            return sqlList;
        } catch (Exception ex) {
            throw new Exception(ex.getMessage());
        } finally {
            IoUtils.closeQuietly(sqlFileIn);
        }
    }

    /**
     * Execute sql.
     *
     * @param conn    connect.
     * @param sqlFile sql.
     * @throws Exception Exception.
     */
    private void execute(Connection conn, String sqlFile) throws Exception {
        try (Statement stmt = conn.createStatement()) {
            List<String> sqlList = loadSql(sqlFile);
            for (String sql : sqlList) {
                try {
                    stmt.execute(sql);
                } catch (Exception e) {
                    LogUtil.DEFAULT_LOG.warn(e.getMessage());
                }
            }
        }
    }
}

18 Source : EventHandlerService.java
with Apache License 2.0
from zhihuili

/**
 * @author leeyazhou
 */
public clreplaced EventHandlerService extends BaseService {

    private static final Logger logger = LoggerFactory.getLogger(EventHandlerService.clreplaced);

    private static final ExecutorService executorService = new ThreadPoolExecutor(32, 64, 60, TimeUnit.SECONDS, new LinkedBlockingQueue<>(), new NamedThreadFactory("flower-ddd-"));

    private DDDConfig dddConfig;

    private TransactionTemplate transactionTemplate;

    public EventHandlerService(DDDConfig dddConfig) {
        this.dddConfig = dddConfig;
    }

    @Override
    public Object doProcess(Object message, ServiceContext context) throws Throwable {
        return CompletableFuture.supplyAsync(() -> {
            try {
                return handleEvent(message, context);
            } catch (Exception e) {
                logger.error("", e);
            }
            return null;
        }, executorService);
    }

    public void setTransactionTemplate(TransactionTemplate transactionTemplate) {
        this.transactionTemplate = transactionTemplate;
    }

    @SuppressWarnings("unchecked")
    private List<Object> handleEvent(Object message, ServiceContext context) {
        final List<EventMessage> messages = new ArrayList<>();
        if (message instanceof List) {
            messages.addAll((List<EventMessage>) message);
        } else {
            messages.add(EventMessage.asEventMessage(messages));
        }
        Supplier<List<Object>> callback = () -> {
            List<Object> ret = new ArrayList<>();
            for (EventMessage item : messages) {
                Set<MethodProxy> methods = dddConfig.getEventHandler(item.getMessage().getClreplaced());
                if (methods == null || methods.isEmpty()) {
                    throw new EventHandlerNotFoundException("for " + message.getClreplaced());
                }
                for (MethodProxy method : methods) {
                    ret.add(method.invoke(item.getMessage(), context));
                }
            }
            return ret;
        };
        boolean isInTransaction = messages.stream().anyMatch(item -> {
            Set<MethodProxy> methodProxies = dddConfig.getEventHandler(item.getMessage().getClreplaced());
            if (methodProxies == null || methodProxies.isEmpty()) {
                return false;
            }
            return methodProxies.stream().anyMatch(m -> {
                return m != null && m.isTransactional();
            });
        });
        if (isInTransaction && transactionTemplate != null) {
            return transactionTemplate.execute(status -> callback.get());
        }
        return callback.get();
    }
}

18 Source : DDDBeanPostProssor.java
with Apache License 2.0
from zhihuili

@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
    if (bean instanceof EventHandlerService) {
        String[] names = applicationContext.getBeanNamesForType(TransactionTemplate.clreplaced);
        if (names != null && names.length > 0) {
            TransactionTemplate transactionTemplate = applicationContext.getBean(TransactionTemplate.clreplaced);
            if (transactionTemplate != null) {
                ((EventHandlerService) bean).setTransactionTemplate(transactionTemplate);
            }
        }
    }
    return bean;
}

18 Source : QueuePickTaskDaoTest.java
with MIT License
from yoomoney-tech

/**
 * @author Oleg Kandaurov
 * @since 15.07.2017
 */
@Ignore
public abstract clreplaced QueuePickTaskDaoTest {

    protected final JdbcTemplate jdbcTemplate;

    protected final TransactionTemplate transactionTemplate;

    protected final String tableName;

    protected final QueueTableSchema tableSchema;

    private final QueueDao queueDao;

    private final Function<PickTaskSettings, QueuePickTaskDao> pickTaskDaoFactory;

    /**
     * Из-за особенностей windows какая-то фигня со временем БД
     */
    private final static Duration WINDOWS_OS_DELAY = Duration.ofSeconds(2);

    public QueuePickTaskDaoTest(QueueDao queueDao, Function<PickTaskSettings, QueuePickTaskDao> pickTaskDaoFactory, String tableName, QueueTableSchema tableSchema, JdbcTemplate jdbcTemplate, TransactionTemplate transactionTemplate) {
        this.tableName = tableName;
        this.tableSchema = tableSchema;
        this.transactionTemplate = transactionTemplate;
        this.jdbcTemplate = jdbcTemplate;
        this.queueDao = queueDao;
        this.pickTaskDaoFactory = pickTaskDaoFactory;
    }

    @Test
    public void should_not_pick_task_too_early() throws Exception {
        QueueLocation location = generateUniqueLocation();
        executeInTransaction(() -> queueDao.enqueue(location, new EnqueueParams<String>().withExecutionDelay(Duration.ofHours(1))));
        QueuePickTaskDao pickTaskDao = pickTaskDaoFactory.apply(new PickTaskSettings(TaskRetryType.ARITHMETIC_BACKOFF, Duration.ofMinutes(1)));
        TaskRecord taskRecord = pickTaskDao.pickTask(location);
        replacedert.replacedertThat(taskRecord, is(nullValue()));
    }

    @Test
    public void pick_task_should_return_all_fields() throws Exception {
        QueueLocation location = generateUniqueLocation();
        String payload = "{}";
        ZonedDateTime beforeEnqueue = ZonedDateTime.now();
        long enqueueId = executeInTransaction(() -> queueDao.enqueue(location, EnqueueParams.create(payload)));
        TaskRecord taskRecord = null;
        QueuePickTaskDao pickTaskDao = pickTaskDaoFactory.apply(new PickTaskSettings(TaskRetryType.ARITHMETIC_BACKOFF, Duration.ofMinutes(1)));
        while (taskRecord == null) {
            taskRecord = executeInTransaction(() -> pickTaskDao.pickTask(location));
            try {
                Thread.sleep(20);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
        }
        ZonedDateTime afterEnqueue = ZonedDateTime.now();
        replacedert.replacedertThat(taskRecord, is(not(nullValue())));
        Objects.requireNonNull(taskRecord);
        replacedert.replacedertThat(taskRecord.getAttemptsCount(), equalTo(1L));
        replacedert.replacedertThat(taskRecord.getId(), equalTo(enqueueId));
        replacedert.replacedertThat(taskRecord.getPayload(), equalTo(payload));
        replacedert.replacedertThat(taskRecord.getNextProcessAt(), is(not(nullValue())));
        replacedert.replacedertThat(taskRecord.getCreatedAt().isAfter(beforeEnqueue), equalTo(true));
        replacedert.replacedertThat(taskRecord.getCreatedAt().isBefore(afterEnqueue), equalTo(true));
    }

    @Test
    public void pick_task_should_delay_with_linear_strategy() {
        QueueLocation location = generateUniqueLocation();
        Duration expectedDelay = Duration.ofMinutes(3L);
        ZonedDateTime beforePickingTask;
        ZonedDateTime afterPickingTask;
        TaskRecord taskRecord;
        PickTaskSettings pickTaskSettings = new PickTaskSettings(TaskRetryType.LINEAR_BACKOFF, Duration.ofMinutes(3));
        QueuePickTaskDao pickTaskDao = pickTaskDaoFactory.apply(pickTaskSettings);
        Long enqueueId = executeInTransaction(() -> queueDao.enqueue(location, new EnqueueParams<>()));
        for (int attempt = 1; attempt < 10; attempt++) {
            beforePickingTask = ZonedDateTime.now();
            taskRecord = resetProcessTimeAndPick(location, pickTaskDao, enqueueId);
            afterPickingTask = ZonedDateTime.now();
            replacedert.replacedertThat(taskRecord.getAttemptsCount(), equalTo((long) attempt));
            replacedert.replacedertThat(taskRecord.getNextProcessAt().isAfter(beforePickingTask.plus(expectedDelay.minus(WINDOWS_OS_DELAY))), equalTo(true));
            replacedert.replacedertThat(taskRecord.getNextProcessAt().isBefore(afterPickingTask.plus(expectedDelay).plus(WINDOWS_OS_DELAY)), equalTo(true));
        }
    }

    @Test
    public void pick_task_should_delay_with_arithmetic_strategy() {
        QueueLocation location = generateUniqueLocation();
        Duration expectedDelay;
        ZonedDateTime beforePickingTask;
        ZonedDateTime afterPickingTask;
        TaskRecord taskRecord;
        PickTaskSettings pickTaskSettings = new PickTaskSettings(TaskRetryType.ARITHMETIC_BACKOFF, Duration.ofMinutes(1));
        QueuePickTaskDao pickTaskDao = pickTaskDaoFactory.apply(pickTaskSettings);
        Long enqueueId = executeInTransaction(() -> queueDao.enqueue(location, new EnqueueParams<>()));
        for (int attempt = 1; attempt < 10; attempt++) {
            beforePickingTask = ZonedDateTime.now();
            taskRecord = resetProcessTimeAndPick(location, pickTaskDao, enqueueId);
            afterPickingTask = ZonedDateTime.now();
            expectedDelay = Duration.ofMinutes(1 + (attempt - 1) * 2);
            replacedert.replacedertThat(taskRecord.getAttemptsCount(), equalTo((long) attempt));
            replacedert.replacedertThat(taskRecord.getNextProcessAt().isAfter(beforePickingTask.plus(expectedDelay.minus(WINDOWS_OS_DELAY))), equalTo(true));
            replacedert.replacedertThat(taskRecord.getNextProcessAt().isBefore(afterPickingTask.plus(expectedDelay.plus(WINDOWS_OS_DELAY))), equalTo(true));
        }
    }

    @Test
    public void pick_task_should_delay_with_geometric_strategy() {
        QueueLocation location = generateUniqueLocation();
        Duration expectedDelay;
        ZonedDateTime beforePickingTask;
        ZonedDateTime afterPickingTask;
        TaskRecord taskRecord;
        PickTaskSettings pickTaskSettings = new PickTaskSettings(TaskRetryType.GEOMETRIC_BACKOFF, Duration.ofMinutes(1));
        QueuePickTaskDao pickTaskDao = pickTaskDaoFactory.apply(pickTaskSettings);
        Long enqueueId = executeInTransaction(() -> queueDao.enqueue(location, new EnqueueParams<>()));
        for (int attempt = 1; attempt < 10; attempt++) {
            beforePickingTask = ZonedDateTime.now();
            taskRecord = resetProcessTimeAndPick(location, pickTaskDao, enqueueId);
            afterPickingTask = ZonedDateTime.now();
            expectedDelay = Duration.ofMinutes(BigInteger.valueOf(2L).pow(attempt - 1).longValue());
            replacedert.replacedertThat(taskRecord.getAttemptsCount(), equalTo((long) attempt));
            replacedert.replacedertThat(taskRecord.getNextProcessAt().isAfter(beforePickingTask.plus(expectedDelay.minus(WINDOWS_OS_DELAY))), equalTo(true));
            replacedert.replacedertThat(taskRecord.getNextProcessAt().isBefore(afterPickingTask.plus(expectedDelay.plus(WINDOWS_OS_DELAY))), equalTo(true));
        }
    }

    private TaskRecord resetProcessTimeAndPick(QueueLocation location, QueuePickTaskDao pickTaskDao, Long enqueueId) {
        executeInTransaction(() -> {
            jdbcTemplate.update("update " + tableName + " set " + tableSchema.getNextProcessAtField() + "= " + currentTimeSql() + " where " + tableSchema.getIdField() + "=" + enqueueId);
        });
        TaskRecord taskRecord = null;
        while (taskRecord == null) {
            taskRecord = executeInTransaction(() -> pickTaskDao.pickTask(location));
            try {
                Thread.sleep(20);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
        }
        return taskRecord;
    }

    protected abstract String currentTimeSql();

    protected QueueLocation generateUniqueLocation() {
        return QueueLocation.builder().withTableName(tableName).withQueueId(new QueueId("test-queue-" + UUID.randomUUID())).build();
    }

    protected void executeInTransaction(Runnable runnable) {
        transactionTemplate.execute(new TransactionCallbackWithoutResult() {

            @Override
            protected void doInTransactionWithoutResult(TransactionStatus status) {
                runnable.run();
            }
        });
    }

    protected <T> T executeInTransaction(Supplier<T> supplier) {
        return transactionTemplate.execute(status -> supplier.get());
    }
}

18 Source : QueueDaoTest.java
with MIT License
from yoomoney-tech

/**
 * @author Oleg Kandaurov
 * @author Behrooz Shabani
 * @since 25.01.2020
 */
@Ignore
public abstract clreplaced QueueDaoTest {

    protected final JdbcTemplate jdbcTemplate;

    protected final TransactionTemplate transactionTemplate;

    protected final String tableName;

    protected final QueueTableSchema tableSchema;

    public QueueDao queueDao;

    public QueueDaoTest(QueueDao queueDao, String tableName, QueueTableSchema tableSchema, JdbcTemplate jdbcTemplate, TransactionTemplate transactionTemplate) {
        this.queueDao = queueDao;
        this.tableName = tableName;
        this.tableSchema = tableSchema;
        this.transactionTemplate = transactionTemplate;
        this.jdbcTemplate = jdbcTemplate;
    }

    @Test
    public void enqueue_should_accept_null_values() throws Exception {
        QueueLocation location = generateUniqueLocation();
        long enqueueId = queueDao.enqueue(location, new EnqueueParams<>());
        replacedert.replacedertThat(enqueueId, not(equalTo(0)));
    }

    @Test
    public void enqueue_should_save_all_values() throws Exception {
        QueueLocation location = generateUniqueLocation();
        String payload = "{}";
        Duration executionDelay = Duration.ofHours(1L);
        ZonedDateTime beforeExecution = ZonedDateTime.now();
        long enqueueId = executeInTransaction(() -> queueDao.enqueue(location, EnqueueParams.create(payload).withExecutionDelay(executionDelay)));
        jdbcTemplate.query("select * from " + tableName + " where " + tableSchema.getIdField() + "=" + enqueueId, rs -> {
            ZonedDateTime afterExecution = ZonedDateTime.now();
            replacedert.replacedertThat(rs.next(), equalTo(true));
            replacedert.replacedertThat(rs.getString(tableSchema.getPayloadField()), equalTo(payload));
            ZonedDateTime nextProcessAt = ZonedDateTime.ofInstant(rs.getTimestamp(tableSchema.getNextProcessAtField()).toInstant(), ZoneId.systemDefault());
            replacedert.replacedertThat(nextProcessAt.isAfter(beforeExecution.plus(executionDelay)), equalTo(true));
            replacedert.replacedertThat(nextProcessAt.isBefore(afterExecution.plus(executionDelay)), equalTo(true));
            ZonedDateTime createdAt = ZonedDateTime.ofInstant(rs.getTimestamp(tableSchema.getCreatedAtField()).toInstant(), ZoneId.systemDefault());
            replacedert.replacedertThat(createdAt.isAfter(beforeExecution), equalTo(true));
            replacedert.replacedertThat(createdAt.isBefore(afterExecution), equalTo(true));
            long reenqueueAttempt = rs.getLong(tableSchema.getReenqueueAttemptField());
            replacedert.replacedertFalse(rs.wasNull());
            replacedert.replacedertEquals(0L, reenqueueAttempt);
            return new Object();
        });
    }

    @Test
    public void delete_should_return_false_when_no_deletion() throws Exception {
        QueueLocation location = generateUniqueLocation();
        Boolean deleteResult = executeInTransaction(() -> queueDao.deleteTask(location, 0L));
        replacedert.replacedertThat(deleteResult, equalTo(false));
    }

    @Test
    public void delete_should_return_true_when_deletion_occur() throws Exception {
        QueueLocation location = generateUniqueLocation();
        Long enqueueId = executeInTransaction(() -> queueDao.enqueue(location, new EnqueueParams<>()));
        Boolean deleteResult = executeInTransaction(() -> queueDao.deleteTask(location, enqueueId));
        replacedert.replacedertThat(deleteResult, equalTo(true));
        jdbcTemplate.query("select * from " + tableName + " where " + tableSchema.getIdField() + "=" + enqueueId, rs -> {
            replacedert.replacedertThat(rs.next(), equalTo(false));
            return new Object();
        });
    }

    @Test
    public void reenqueue_should_update_next_process_time() throws Exception {
        QueueLocation location = generateUniqueLocation();
        Long enqueueId = executeInTransaction(() -> queueDao.enqueue(location, new EnqueueParams<>()));
        ZonedDateTime beforeExecution = ZonedDateTime.now();
        Duration executionDelay = Duration.ofHours(1L);
        Boolean reenqueueResult = executeInTransaction(() -> queueDao.reenqueue(location, enqueueId, executionDelay));
        replacedert.replacedertThat(reenqueueResult, equalTo(true));
        jdbcTemplate.query("select * from " + tableName + " where " + tableSchema.getIdField() + "=" + enqueueId, rs -> {
            ZonedDateTime afterExecution = ZonedDateTime.now();
            replacedert.replacedertThat(rs.next(), equalTo(true));
            ZonedDateTime nextProcessAt = ZonedDateTime.ofInstant(rs.getTimestamp(tableSchema.getNextProcessAtField()).toInstant(), ZoneId.systemDefault());
            replacedert.replacedertThat(nextProcessAt.isAfter(beforeExecution.plus(executionDelay)), equalTo(true));
            replacedert.replacedertThat(nextProcessAt.isBefore(afterExecution.plus(executionDelay)), equalTo(true));
            return new Object();
        });
    }

    @Test
    public void reenqueue_should_reset_attempts() throws Exception {
        QueueLocation location = generateUniqueLocation();
        Long enqueueId = executeInTransaction(() -> queueDao.enqueue(location, new EnqueueParams<>()));
        executeInTransaction(() -> {
            jdbcTemplate.update("update " + tableName + " set " + tableSchema.getAttemptField() + "=10 where " + tableSchema.getIdField() + "=" + enqueueId);
        });
        jdbcTemplate.query("select * from " + tableName + " where " + tableSchema.getIdField() + "=" + enqueueId, rs -> {
            replacedert.replacedertThat(rs.next(), equalTo(true));
            replacedert.replacedertThat(rs.getLong(tableSchema.getAttemptField()), equalTo(10L));
            return new Object();
        });
        Boolean reenqueueResult = executeInTransaction(() -> queueDao.reenqueue(location, enqueueId, Duration.ofHours(1L)));
        replacedert.replacedertThat(reenqueueResult, equalTo(true));
        jdbcTemplate.query("select * from " + tableName + " where " + tableSchema.getIdField() + "=" + enqueueId, rs -> {
            replacedert.replacedertThat(rs.next(), equalTo(true));
            replacedert.replacedertThat(rs.getLong(tableSchema.getAttemptField()), equalTo(0L));
            return new Object();
        });
    }

    @Test
    public void reenqueue_should_increment_reenqueue_attempts() {
        QueueLocation location = generateUniqueLocation();
        Long enqueueId = executeInTransaction(() -> queueDao.enqueue(location, new EnqueueParams<>()));
        jdbcTemplate.query("select * from " + tableName + " where " + tableSchema.getIdField() + "=" + enqueueId, rs -> {
            replacedert.replacedertThat(rs.next(), equalTo(true));
            replacedert.replacedertThat(rs.getLong(tableSchema.getReenqueueAttemptField()), equalTo(0L));
            return new Object();
        });
        Boolean reenqueueResult = executeInTransaction(() -> queueDao.reenqueue(location, enqueueId, Duration.ofHours(1L)));
        replacedert.replacedertThat(reenqueueResult, equalTo(true));
        jdbcTemplate.query("select * from " + tableName + " where " + tableSchema.getIdField() + "=" + enqueueId, rs -> {
            replacedert.replacedertThat(rs.next(), equalTo(true));
            replacedert.replacedertThat(rs.getLong(tableSchema.getReenqueueAttemptField()), equalTo(1L));
            return new Object();
        });
    }

    @Test
    public void reenqueue_should_return_false_when_no_update() throws Exception {
        QueueLocation location = generateUniqueLocation();
        Boolean reenqueueResult = executeInTransaction(() -> queueDao.reenqueue(location, 0L, Duration.ofHours(1L)));
        replacedert.replacedertThat(reenqueueResult, equalTo(false));
    }

    protected QueueLocation generateUniqueLocation() {
        return QueueLocation.builder().withTableName(tableName).withQueueId(new QueueId("test-queue-" + UUID.randomUUID())).build();
    }

    protected void executeInTransaction(Runnable runnable) {
        transactionTemplate.execute(new TransactionCallbackWithoutResult() {

            @Override
            protected void doInTransactionWithoutResult(TransactionStatus status) {
                runnable.run();
            }
        });
    }

    protected <T> T executeInTransaction(Supplier<T> supplier) {
        return transactionTemplate.execute(status -> supplier.get());
    }
}

18 Source : SpringTransactionTest.java
with Apache License 2.0
from yihonglei

/**
 * 1)在一个事务内,一个失败,全部失败回滚。
 * 2)如果设置了保存点,可以选择回滚到保存点。
 *
 * @author yihonglei
 */
public static void main(String[] args) {
    final DataSource ds = new DriverManagerDataSource(url, user, preplacedword);
    final TransactionTemplate template = new TransactionTemplate();
    template.setTransactionManager(new DataSourceTransactionManager(ds));
    template.execute(new TransactionCallback<Object>() {

        @Override
        public Object doInTransaction(TransactionStatus status) {
            Connection conn = DataSourceUtils.getConnection(ds);
            Object savePoint = null;
            try {
                {
                    // 插入
                    PreparedStatement prepare = conn.prepareStatement("insert INTO account (accountName,userName,money) VALUES (?,?,?)");
                    prepare.setString(1, "111");
                    prepare.setString(2, "aaa");
                    prepare.setInt(3, 10000);
                    prepare.executeUpdate();
                }
                // 设置保存点,如果设置了保存点,我们可以根据保存点进行回滚
                // savePoint = status.createSavepoint();
                {
                    // 插入
                    PreparedStatement prepare = conn.prepareStatement("insert INTO account (accountName,userName,money) VALUES (?,?,?)");
                    prepare.setString(1, "222");
                    prepare.setString(2, "bbb");
                    prepare.setInt(3, 10000);
                    prepare.executeUpdate();
                }
                {
                    // 更新
                    PreparedStatement prepare = conn.prepareStatement("UPDATE account SET money= money+1 where userName=?");
                    prepare.setString(1, "ccc");
                    // 模拟报错
                    int i = 1 / 0;
                }
            } catch (Exception e) {
                System.out.println("更新失败");
                if (savePoint != null) {
                    // 回滚到保存点
                    status.rollbackToSavepoint(savePoint);
                } else {
                    // 事务回滚
                    status.setRollbackOnly();
                }
            }
            return null;
        }
    });
}

See More Examples