2017-03-08 19 views
0

私は以下のクエリを異なる日付範囲で呼び出すexecutorserviceを作成しました。同期を実行すると、エラーは表示されません。私はgetTransactionResultを起動するために並行してスレッドの数を開始しかし、私が見るSpring JDBCTemplate - Concurrent Calls

java.util.concurrent.ExecutionException: org.springframework.dao.DataIntegrityViolationException: PreparedStatementCallback。 SQL [クエリ]; ORA-01841:(完全)年は-4713〜+9999の間で であり、0ではありません。 ORA-01841:(フル)年 -4713と+9999の間で、及びjava.util.concurrent.FutureTask.reportで0

てはなりません(FutureTask.java入れ子の例外は java.sql.SQLDataExceptionです:122)at java.util.concurrent.FutureTask.get(FutureTask.java:192)at com.cloud.cloudreport.CloudReportApplication.lambda $ 1(CloudReportApplication.java:94) at java.util.ArrayList.forEach ArrayList.java:1249) でcom.cloud.cloudreport.CloudReportApplication.run(CloudReportApplication.java:92) org.springframework.boot.SpringApplication.callRunner(SpringApplication.java:776) における時または org.springframework.boot.SpringApplication.run(SpringApplicationでg.springframework.boot.SpringApplication.callRunners(SpringApplication.java:760) でorg.springframework.boot.SpringApplication.afterRefresh(SpringApplication.java:747) 。ジャワ:315) でorg.springframework.boot.SpringApplication.run(SpringApplication.java:1162) でorg.springframework.boot.SpringApplication.run(SpringApplication.java:1151) com.cloud.cloudreportで.CloudReportApplication.main(CloudReportApplication.java:43) 原因:org.springframework.dao.DataIntegrityViolationException: PreparedStatementCallback; SQL []; ORA-01841:(完全)年は で、-4713〜+9999の間でなければなりません。 -4713と+9999の間で、及び org.springframework.jdbc.support.SQLExceptionSubclassTranslator.doTranslate(で0

てはなりません(フル)年:ORA-01841:ネストされた例外は java.sql.SQLDataExceptionですSQLExceptionSubclassTranslator.java:82) でorg.springframework.jdbc.support.AbstractFallbackSQLExceptionTranslator.translate(AbstractFallbackSQLExceptionTranslator.java:73) org.springframework.jdbc.support.AbstractFallbackSQLExceptionTranslator.translate(AbstractFallbackSQLExceptionTranslator.java:81) でで org.springframework.jdbc.core.JdbcTemplate.execute(JdbcTemplate.java:649) でorg.springframework.jdbc.core.JdbcTemplate.query(JdbcTemplate.java:684) でorg.springframework.jdbc.core.JdbcTemplate.query(JdbcTemplate.java:711) org.springframework.jdbcで com.cloud.cloudreport.dao.TransactionRespository.getTransactionResultで.core.JdbcTemplate.query org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate.queryForObject(NamedParameterJdbcTemplate.java:211)で(JdbcTemplate.java:761) (TransactionRespository.java:68) at com.cloudreport.dao.TransactionRespository $$ FastClassBySpringCGLIB $$ 60dee75d.invoke() at 組織.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy。Javaの:204) でorg.springframework.aop.framework.CglibAopProxy $ CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:721) で org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:157) で org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:136) でorg.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179) org.springframework.aop.frameworkで.CglibAopProxy $ DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:656) at com.cloud.cloudre port.dao.TransactionRespository $$ $$ EnhancerBySpringCGLIB ca18ee4e.getTransactionResult()java.util.concurrent.FutureTask.runで でcom.cloud.cloudreport.CloudReportApplication.lambda $ 0(CloudReportApplication.java:76) (FutureTask.java :266) java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)で でjava.util.concurrent.ThreadPoolExecutor $ Worker.run(ThreadPoolExecutor.java:617)java.lang.Threadので 。 java.sql.SQLDataException:ORA-01841:によって引き起こさラン(Thread.java:745)(フル)年には、 -4713と+9999の間で、及びoracle.jdbc.driverで0

あってはなりません.T4CTTIoer.pr のoracle.jdbcでoracle.jdbc.driver.T4C8Oall.processError(T4C8Oall.java:1017)で oracle.jdbc.driver.T4CTTIoer.processError(T4CTTIoer.java:399)でocessError(T4CTTIoer.java:450)。 でoracle.jdbc.driver.T4C8Oall.doOALL(T4C8Oall.java:566)で oracle.jdbc.driver.T4CTTIfun.doRPC(T4CTTIfun.java:249)でdriver.T4CTTIfun.receive(T4CTTIfun.java:655) oracle.jdbc.driver.T4CPreparedStatement.doOall8(T4CPreparedStatement.java:215) でoracle.jdbc.driver.T4CPreparedStatement.doOall8(T4CPreparedStatement.java:58) oracle.jdbc.driver.T4CPreparedStatement.executeForDescribe(T4CPreparedStatementで 。 java:776) at oracle.jdbc.drive oracle.jdbc.driver.OraclePreparedStatement.executeInternal(OraclePreparedStatement.java:3820)でr.OracleStatement.executeMaybeDescribe(OracleStatement.java:897) でoracle.jdbc.driver.OracleStatement.doExecuteWithTimeout(OracleStatement.java:1034) でoracle.jdbc.driver.OraclePreparedStatement.executeQuery(OraclePreparedStatement.java:3867) でoracle.jdbc.driver.OraclePreparedStatementWrapper.executeQuery(OraclePreparedStatementWrapper.java:1502) org.springframework.jdbc.core.JdbcTemplateで(JdbcTemplate.execute(JdbcTemplate.execute)) java:633) ... 18 more

parellelでメソッドを実行するために必要な変更はありますか?

@Repository 
public class TransactionRespository { 
    private static Logger LOG = LoggerFactory.getLogger(TransactionRespository.class); 

    @Autowired 
    private NamedParameterJdbcTemplate jdbcTemplate; 

    private String transactionQuery = " query goes here"; 

    public TransactionDetails getTransactionResult(String serviceName, String operationName, Date startDate, 
      Date endDate) { 

     SqlParameterSource namedParameters = new MapSqlParameterSource("serviceName", serviceName) 
       .addValue("operationName", operationName) 
       .addValue("startDate", new DateTime(startDate).toString("yyyy-MM-dd HH:mm:ss")) 
       .addValue("endDate", new DateTime(endDate).toString("yyyy-MM-dd HH:mm:ss")); 

     try{ 
      return (TransactionDetails) this.jdbcTemplate.queryForObject(transactionQuery, namedParameters,(rs,rowNum)->{ 
       TransactionDetails transactionDetails = new TransactionDetails(); 
       TransactionResult result = new TransactionResult(); 
       transactionDetails.setStartDate(new DateTime(startDate).toString("yyyy-MM-dd HH:mm:ss")); 
       transactionDetails.setEndDate(new DateTime(endDate).toString("yyyy-MM-dd HH:mm:ss")); 
       result.setSuccessfulTransactions(rs.getInt(2)); 
       result.setFailedTransactions(rs.getInt(3)); 
       Map<String,TransactionResult> operationResult = new TreeMap<>(); 
       operationResult.put(operationName, result); 
       transactionDetails.setOperationResult(operationResult); 

       return transactionDetails; 
      });   
     } catch (EmptyResultDataAccessException e) { 
      LOG.debug("start date :: {} , end date :: {} " , new DateTime(startDate).toString("yyyy-MM-dd HH:mm:ss"), new DateTime(endDate).toString("yyyy-MM-dd HH:mm:ss")); 
      return null; 
     } 


    } 
+0

に従うことができます。 –

+0

確か@JBNizet、私は今stacktraceを更新しました。私が見ている例外は、連続して実行しているときには発生せず、並列実行中にいくつかの場合には発生しません。 –

+1

例外は、パラメータに何とか無効な日付を渡していることを明確に示しています。*(完全)年は、-4713から+9999の間で、0 *でない必要があります。最初の匂いは、DateまたはTimestampタイプを使用する代わりに、日付を文字列として渡すことです。データを確認してください。 –

答えて

1

getTransactionResult(...)には同期がありません。コンテナはものを管理することができますが、あなたが注文を維持するのはあなた次第です。コンテナには、同期が必要なものを知る方法がありません。

あなたは例外について尋ねたとき、常に例外の完全なスタックトレースを投稿する方法を同期するか、またはこの

synchronized method or use spring @transactional?

+0

両方のオプションを使用してみましたが、トランザクションは順次処理されています。しかし、私はそれらを並行して実行したい。 –

+0

私はそれの中にブレークポイントを置くでしょう。スレッドを実行し、ヒット数を確認してください。そこから行く – efekctive

+0

確かに@efekctive。私はそれを試みます –

関連する問題