use of java.sql.BatchUpdateException in project ignite by apache.
the class DmlUtils method doInsertBatched.
/**
* Execute INSERT statement plan.
*
* @param plan Plan to execute.
* @param cursor Cursor to take inserted data from. I.e. list of batch arguments for each query.
* @param pageSize Batch size for streaming, anything <= 0 for single page operations.
* @return Number of items affected.
* @throws IgniteCheckedException if failed, particularly in case of duplicate keys.
*/
private static List<UpdateResult> doInsertBatched(UpdatePlan plan, List<List<List<?>>> cursor, int pageSize) throws IgniteCheckedException {
GridCacheContext cctx = plan.cacheContext();
DmlBatchSender snd = new DmlBatchSender(cctx, pageSize, cursor.size());
int rowNum = 0;
SQLException resEx = null;
for (List<List<?>> qryRow : cursor) {
for (List<?> row : qryRow) {
try {
final IgniteBiTuple keyValPair = plan.processRow(row);
snd.add(keyValPair.getKey(), new DmlStatementsProcessor.InsertEntryProcessor(keyValPair.getValue()), rowNum);
} catch (Exception e) {
String sqlState;
int code;
if (e instanceof IgniteSQLException) {
sqlState = ((IgniteSQLException) e).sqlState();
code = ((IgniteSQLException) e).statusCode();
} else {
sqlState = SqlStateCode.INTERNAL_ERROR;
code = IgniteQueryErrorCode.UNKNOWN;
}
resEx = chainException(resEx, new SQLException(e.getMessage(), sqlState, code, e));
snd.setFailed(rowNum);
}
}
rowNum++;
}
try {
snd.flush();
} catch (Exception e) {
resEx = chainException(resEx, new SQLException(e.getMessage(), SqlStateCode.INTERNAL_ERROR, IgniteQueryErrorCode.UNKNOWN, e));
}
resEx = chainException(resEx, snd.error());
if (!F.isEmpty(snd.failedKeys())) {
SQLException e = new SQLException("Failed to INSERT some keys because they are already in cache [keys=" + snd.failedKeys() + ']', SqlStateCode.CONSTRAINT_VIOLATION, DUPLICATE_KEY);
resEx = chainException(resEx, e);
}
if (resEx != null) {
BatchUpdateException e = new BatchUpdateException(resEx.getMessage(), resEx.getSQLState(), resEx.getErrorCode(), snd.perRowCounterAsArray(), resEx);
throw new IgniteCheckedException(e);
}
int[] cntPerRow = snd.perRowCounterAsArray();
List<UpdateResult> res = new ArrayList<>(cntPerRow.length);
for (int i = 0; i < cntPerRow.length; i++) {
int cnt = cntPerRow[i];
res.add(new UpdateResult(cnt, X.EMPTY_OBJECT_ARRAY));
}
return res;
}
use of java.sql.BatchUpdateException in project ignite by apache.
the class IgniteH2Indexing method executeUpdateDistributed.
/**
* @param qryId Query id.
* @param qryDesc Query descriptor.
* @param qryParams Query parameters.
* @param dml DML statement.
* @param cancel Query cancel.
* @return Update result wrapped into {@link GridQueryFieldsResult}
* @throws IgniteCheckedException if failed.
*/
@SuppressWarnings("unchecked")
private List<QueryCursorImpl<List<?>>> executeUpdateDistributed(long qryId, QueryDescriptor qryDesc, QueryParameters qryParams, QueryParserResultDml dml, GridQueryCancel cancel) throws IgniteCheckedException {
if (qryDesc.batched()) {
Collection<UpdateResult> ress;
List<Object[]> argss = qryParams.batchedArguments();
UpdatePlan plan = dml.plan();
GridCacheContext<?, ?> cctx = plan.cacheContext();
// For MVCC case, let's enlist batch elements one by one.
if (plan.hasRows() && plan.mode() == UpdateMode.INSERT && !cctx.mvccEnabled()) {
CacheOperationContext opCtx = DmlUtils.setKeepBinaryContext(cctx);
try {
List<List<List<?>>> cur = plan.createRows(argss);
// TODO: IGNITE-11176 - Need to support cancellation
ress = DmlUtils.processSelectResultBatched(plan, cur, qryParams.updateBatchSize());
} finally {
DmlUtils.restoreKeepBinaryContext(cctx, opCtx);
}
} else {
// Fallback to previous mode.
ress = new ArrayList<>(argss.size());
SQLException batchException = null;
int[] cntPerRow = new int[argss.size()];
int cntr = 0;
for (Object[] args : argss) {
UpdateResult res;
try {
res = executeUpdate(qryId, qryDesc, qryParams.toSingleBatchedArguments(args), dml, false, null, cancel);
cntPerRow[cntr++] = (int) res.counter();
ress.add(res);
} catch (Exception e) {
SQLException sqlEx = QueryUtils.toSqlException(e);
batchException = DmlUtils.chainException(batchException, sqlEx);
cntPerRow[cntr++] = Statement.EXECUTE_FAILED;
}
}
if (batchException != null) {
BatchUpdateException e = new BatchUpdateException(batchException.getMessage(), batchException.getSQLState(), batchException.getErrorCode(), cntPerRow, batchException);
throw new IgniteCheckedException(e);
}
}
ArrayList<QueryCursorImpl<List<?>>> resCurs = new ArrayList<>(ress.size());
for (UpdateResult res : ress) {
res.throwIfError();
QueryCursorImpl<List<?>> resCur = (QueryCursorImpl<List<?>>) new QueryCursorImpl(singletonList(singletonList(res.counter())), cancel, false, false);
resCur.fieldsMeta(UPDATE_RESULT_META);
resCurs.add(resCur);
}
return resCurs;
} else {
UpdateResult res = executeUpdate(qryId, qryDesc, qryParams, dml, false, null, cancel);
res.throwIfError();
QueryCursorImpl<List<?>> resCur = (QueryCursorImpl<List<?>>) new QueryCursorImpl(singletonList(singletonList(res.counter())), cancel, false, false);
resCur.fieldsMeta(UPDATE_RESULT_META);
resCur.partitionResult(res.partitionResult());
return singletonList(resCur);
}
}
use of java.sql.BatchUpdateException in project dal by ctripcorp.
the class DalCommandTest method testThreeLayerExceptionTransaction.
// Three layer transaction throws exception
@Test
public void testThreeLayerExceptionTransaction() throws Exception {
DalClient client = DalClientFactory.getClient(dbName);
try {
client.execute(new OneLayerExceptionDalCommand(), new DalHints());
Assert.fail();
} catch (Throwable e) {
System.out.println(e.getMessage());
Assert.assertTrue(e instanceof BatchUpdateException);
Assert.assertTrue(e.getMessage().equals("Data truncation: Data too long for column 'Name' at row 1"));
Assert.assertTrue(isCurrentTransactionNull());
}
}
use of java.sql.BatchUpdateException in project dal by ctripcorp.
the class DalCommandTest method testBatchOperationThrowExceptionInDalCommand.
// Two layer transaction with exception which should throws actual exception
@Test
public void testBatchOperationThrowExceptionInDalCommand() throws Exception {
DalClient client = DalClientFactory.getClient(dbName);
try {
client.execute(new ThrowExceptionDalCommand(), new DalHints());
Assert.fail();
} catch (Throwable e) {
System.out.println(e.getMessage());
Assert.assertTrue(e instanceof BatchUpdateException);
Assert.assertTrue(e.getMessage().equals("Data truncation: Data too long for column 'Name' at row 1"));
Assert.assertTrue(isCurrentTransactionNull());
}
}
use of java.sql.BatchUpdateException in project dal by ctripcorp.
the class DalCommandTest method testFourLayerExceptionTransaction.
// Four layer transaction throws exception
@Test
public void testFourLayerExceptionTransaction() throws Exception {
DalClient client = DalClientFactory.getClient(dbName);
try {
client.execute(new TwoLayerExceptionDalCommand(), new DalHints());
Assert.fail();
} catch (Throwable e) {
System.out.println(e.getMessage());
Assert.assertTrue(e instanceof BatchUpdateException);
Assert.assertTrue(e.getMessage().equals("Data truncation: Data too long for column 'Name' at row 1"));
Assert.assertTrue(isCurrentTransactionNull());
}
}
Aggregations