use of org.jumpmind.db.sql.ISqlTransaction in project symmetric-ds by JumpMind.
the class AbstractRouterServiceTest method testDontSelectOldDataDuringRouting.
public void testDontSelectOldDataDuringRouting() throws Exception {
NodeChannel testChannel = getConfigurationService().getNodeChannel(TestConstants.TEST_CHANNEL_ID, false);
testChannel.setUseOldDataToRoute(false);
testChannel.setMaxBatchSize(50);
testChannel.setBatchAlgorithm("nontransactional");
getConfigurationService().saveChannel(testChannel, true);
TriggerRouter trigger = getTestRoutingTableTrigger(TEST_TABLE_1);
trigger.getRouter().setRouterType("column");
trigger.getRouter().setRouterExpression("ROUTING_VARCHAR=:NODE_ID");
getTriggerRouterService().saveTriggerRouter(trigger);
// clean setup
deleteAll(TEST_TABLE_1);
insert(TEST_TABLE_1, 100, true);
getRouterService().routeData(true);
resetBatches();
// delete
deleteAll(TEST_TABLE_1);
ISqlTransaction transaction = getSqlTemplate().startSqlTransaction();
ChannelRouterContext context = new ChannelRouterContext(TestConstants.TEST_ROOT_EXTERNAL_ID, testChannel, transaction);
DataGapRouteReader reader = new DataGapRouteReader(context, engine);
reader.run();
List<Data> list = new ArrayList<Data>();
do {
Data data = reader.take();
if (data != null) {
list.add(data);
} else {
break;
}
} while (true);
transaction.close();
Assert.assertEquals(100, list.size());
for (Data data : list) {
Assert.assertNull(data.toParsedOldData());
Assert.assertNotNull(data.toParsedPkData());
}
}
use of org.jumpmind.db.sql.ISqlTransaction in project symmetric-ds by JumpMind.
the class AbstractRouterServiceTest method execute.
protected void execute(final String sql, final String node2disable) {
ISymmetricDialect dialect = getDbDialect();
IDatabasePlatform platform = dialect.getPlatform();
ISqlTransaction transaction = null;
try {
transaction = platform.getSqlTemplate().startSqlTransaction();
if (node2disable != null) {
dialect.disableSyncTriggers(transaction, node2disable);
}
transaction.prepareAndExecute(sql);
if (node2disable != null) {
dialect.enableSyncTriggers(transaction);
}
transaction.commit();
} finally {
if (transaction != null) {
transaction.close();
}
}
}
use of org.jumpmind.db.sql.ISqlTransaction in project symmetric-ds by JumpMind.
the class DataExtractorService method execute.
/**
* This is a callback method used by the NodeCommunicationService that
* extracts an initial load in the background.
*/
public void execute(NodeCommunication nodeCommunication, RemoteNodeStatus status) {
long ts = System.currentTimeMillis();
List<ExtractRequest> requests = getExtractRequestsForNode(nodeCommunication.getNodeId());
/*
* Process extract requests until it has taken longer than 30 seconds,
* and then allow the process to return so progress status can be seen.
*/
for (int i = 0; i < requests.size() && (System.currentTimeMillis() - ts) <= Constants.LONG_OPERATION_THRESHOLD; i++) {
ExtractRequest request = requests.get(i);
Node identity = nodeService.findIdentity();
Node targetNode = nodeService.findNode(nodeCommunication.getNodeId());
log.info("Extracting batches for request {}. Starting at batch {}. Ending at batch {}", new Object[] { request.getRequestId(), request.getStartBatchId(), request.getEndBatchId() });
List<OutgoingBatch> batches = outgoingBatchService.getOutgoingBatchRange(request.getStartBatchId(), request.getEndBatchId()).getBatches();
ProcessInfo processInfo = statisticManager.newProcessInfo(new ProcessInfoKey(identity.getNodeId(), nodeCommunication.getNodeId(), ProcessType.INITIAL_LOAD_EXTRACT_JOB));
try {
boolean areBatchesOk = true;
/*
* check to see if batches have been OK'd by another reload
* request
*/
for (OutgoingBatch outgoingBatch : batches) {
if (outgoingBatch.getStatus() != Status.OK) {
areBatchesOk = false;
}
}
if (!areBatchesOk) {
Channel channel = configurationService.getChannel(batches.get(0).getChannelId());
/*
* "Trick" the extractor to extract one reload batch, but we
* will split it across the N batches when writing it
*/
extractOutgoingBatch(processInfo, targetNode, new MultiBatchStagingWriter(identity.getNodeId(), stagingManager, batches, channel.getMaxBatchSize()), batches.get(0), false, false, ExtractMode.FOR_SYM_CLIENT);
} else {
log.info("Batches already had an OK status for request {}, batches {} to {}. Not extracting", new Object[] { request.getRequestId(), request.getStartBatchId(), request.getEndBatchId() });
}
/*
* re-query the batches to see if they have been OK'd while
* extracting
*/
List<OutgoingBatch> checkBatches = outgoingBatchService.getOutgoingBatchRange(request.getStartBatchId(), request.getEndBatchId()).getBatches();
areBatchesOk = true;
/*
* check to see if batches have been OK'd by another reload
* request while extracting
*/
for (OutgoingBatch outgoingBatch : checkBatches) {
if (outgoingBatch.getStatus() != Status.OK) {
areBatchesOk = false;
}
}
ISqlTransaction transaction = null;
try {
transaction = sqlTemplate.startSqlTransaction();
updateExtractRequestStatus(transaction, request.getRequestId(), ExtractStatus.OK);
if (!areBatchesOk) {
for (OutgoingBatch outgoingBatch : batches) {
outgoingBatch.setStatus(Status.NE);
outgoingBatchService.updateOutgoingBatch(transaction, outgoingBatch);
}
} else {
log.info("Batches already had an OK status for request {}, batches {} to {}. Not updating the status to NE", new Object[] { request.getRequestId(), request.getStartBatchId(), request.getEndBatchId() });
}
transaction.commit();
} catch (Error ex) {
if (transaction != null) {
transaction.rollback();
}
throw ex;
} catch (RuntimeException ex) {
if (transaction != null) {
transaction.rollback();
}
throw ex;
} finally {
close(transaction);
}
processInfo.setStatus(org.jumpmind.symmetric.model.ProcessInfo.Status.OK);
} catch (RuntimeException ex) {
log.debug("Failed to extract batches for request {}. Starting at batch {}. Ending at batch {}", new Object[] { request.getRequestId(), request.getStartBatchId(), request.getEndBatchId() });
processInfo.setStatus(org.jumpmind.symmetric.model.ProcessInfo.Status.ERROR);
throw ex;
}
}
}
use of org.jumpmind.db.sql.ISqlTransaction in project symmetric-ds by JumpMind.
the class DataService method insertReloadEvents.
public void insertReloadEvents(Node targetNode, boolean reverse) {
if (engine.getClusterService().lock(ClusterConstants.SYNCTRIGGERS)) {
try {
synchronized (engine.getTriggerRouterService()) {
engine.getClusterService().lock(ClusterConstants.SYNCTRIGGERS);
if (!reverse) {
log.info("Queueing up an initial load to " + targetNode.getNodeId());
} else {
log.info("Queueing up a reverse initial load to " + targetNode.getNodeId());
}
/*
* Outgoing data events are pointless because we are
* reloading all data
*/
engine.getOutgoingBatchService().markAllAsSentForNode(targetNode.getNodeId(), false);
INodeService nodeService = engine.getNodeService();
ITriggerRouterService triggerRouterService = engine.getTriggerRouterService();
Node sourceNode = nodeService.findIdentity();
boolean transactional = parameterService.is(ParameterConstants.DATA_RELOAD_IS_BATCH_INSERT_TRANSACTIONAL);
String nodeIdRecord = reverse ? nodeService.findIdentityNodeId() : targetNode.getNodeId();
NodeSecurity nodeSecurity = nodeService.findNodeSecurity(nodeIdRecord);
ISqlTransaction transaction = null;
try {
transaction = platform.getSqlTemplate().startSqlTransaction();
long loadId = engine.getSequenceService().nextVal(transaction, Constants.SEQUENCE_OUTGOING_BATCH_LOAD_ID);
String createBy = reverse ? nodeSecurity.getRevInitialLoadCreateBy() : nodeSecurity.getInitialLoadCreateBy();
List<TriggerHistory> triggerHistories = triggerRouterService.getActiveTriggerHistories();
Map<Integer, List<TriggerRouter>> triggerRoutersByHistoryId = triggerRouterService.fillTriggerRoutersByHistIdAndSortHist(sourceNode.getNodeGroupId(), targetNode.getNodeGroupId(), triggerHistories);
callReloadListeners(true, targetNode, transactional, transaction, loadId);
insertCreateSchemaScriptPriorToReload(targetNode, nodeIdRecord, loadId, createBy, transactional, transaction);
insertSqlEventsPriorToReload(targetNode, nodeIdRecord, loadId, createBy, transactional, transaction, reverse);
insertCreateBatchesForReload(targetNode, loadId, createBy, triggerHistories, triggerRoutersByHistoryId, transactional, transaction);
insertDeleteBatchesForReload(targetNode, loadId, createBy, triggerHistories, triggerRoutersByHistoryId, transactional, transaction);
insertLoadBatchesForReload(targetNode, loadId, createBy, triggerHistories, triggerRoutersByHistoryId, transactional, transaction);
String afterSql = parameterService.getString(reverse ? ParameterConstants.INITIAL_LOAD_REVERSE_AFTER_SQL : ParameterConstants.INITIAL_LOAD_AFTER_SQL);
if (isNotBlank(afterSql)) {
insertSqlEvent(transaction, targetNode, afterSql, true, loadId, createBy);
}
insertFileSyncBatchForReload(targetNode, loadId, createBy, transactional, transaction);
callReloadListeners(false, targetNode, transactional, transaction, loadId);
if (!reverse) {
nodeService.setInitialLoadEnabled(transaction, nodeIdRecord, false, false, loadId, createBy);
} else {
nodeService.setReverseInitialLoadEnabled(transaction, nodeIdRecord, false, false, loadId, createBy);
}
if (!Constants.DEPLOYMENT_TYPE_REST.equals(targetNode.getDeploymentType())) {
insertNodeSecurityUpdate(transaction, nodeIdRecord, targetNode.getNodeId(), true, loadId, createBy);
}
engine.getStatisticManager().incrementNodesLoaded(1);
transaction.commit();
} catch (Error ex) {
if (transaction != null) {
transaction.rollback();
}
throw ex;
} catch (RuntimeException ex) {
if (transaction != null) {
transaction.rollback();
}
throw ex;
} finally {
close(transaction);
}
if (!reverse) {
/*
* Remove all incoming events for the node that we are
* starting a reload for
*/
engine.getPurgeService().purgeAllIncomingEventsForNode(targetNode.getNodeId());
}
}
} finally {
engine.getClusterService().unlock(ClusterConstants.SYNCTRIGGERS);
}
} else {
log.info("Not attempting to insert reload events because sync trigger is currently running");
}
}
use of org.jumpmind.db.sql.ISqlTransaction in project symmetric-ds by JumpMind.
the class DataService method insertHeartbeatEvent.
/**
* Because we can't add a trigger on the _node table, we are artificially
* generating heartbeat events.
*
* @param node
*/
public void insertHeartbeatEvent(Node node, boolean isReload) {
ISqlTransaction transaction = null;
try {
transaction = sqlTemplate.startSqlTransaction();
String tableName = TableConstants.getTableName(tablePrefix, TableConstants.SYM_NODE);
List<NodeGroupLink> links = engine.getConfigurationService().getNodeGroupLinksFor(parameterService.getNodeGroupId(), false);
for (NodeGroupLink nodeGroupLink : links) {
if (nodeGroupLink.getDataEventAction() == NodeGroupLinkAction.P) {
Set<TriggerRouter> triggerRouters = engine.getTriggerRouterService().getTriggerRouterForTableForCurrentNode(true, nodeGroupLink, null, null, tableName, false);
if (triggerRouters != null && triggerRouters.size() > 0) {
Data data = createData(transaction, triggerRouters.iterator().next().getTrigger(), String.format(" t.node_id = '%s'", node.getNodeId()));
if (data != null) {
insertData(transaction, data);
} else {
log.warn("Not generating data/data events for table {} " + "because a trigger or trigger hist is not created yet.", tableName);
}
} else {
log.warn("Not generating data/data events for table {} " + "because a trigger or trigger hist is not created yet.", tableName);
}
}
}
transaction.commit();
} catch (Error ex) {
if (transaction != null) {
transaction.rollback();
}
throw ex;
} catch (RuntimeException ex) {
if (transaction != null) {
transaction.rollback();
}
throw ex;
} finally {
close(transaction);
}
}
Aggregations