简体   繁体   English

Spring JDBCTemplate-并发调用

[英]Spring JDBCTemplate - Concurrent Calls

I have created a executorservice to call the below listed query with different date ranges. 我创建了executorservice来调用下面列出的具有不同日期范围的查询。 When I run it synchronously I don't see any errors. 同步运行时,看不到任何错误。 However when I initiate a number of threads in parallel to invoke getTransactionResult , I see 但是,当我并行启动多个线程来调用getTransactionResult时,我看到了

java.util.concurrent.ExecutionException: org.springframework.dao.DataIntegrityViolationException: PreparedStatementCallback; java.util.concurrent.ExecutionException:org.springframework.dao.DataIntegrityViolationException:PreparedStatementCallback; SQL [Query]; SQL [查询]; ORA-01841: (full) year must be between -4713 and +9999, and not be 0 ; ORA-01841 :(完整)年份必须在-4713到+9999之间,并且不能为0; nested exception is java.sql.SQLDataException: ORA-01841: (full) year must be between -4713 and +9999, and not be 0 嵌套异常为java.sql.SQLDataException:ORA-01841 :(完整)年份必须在-4713和+9999之间,并且不能为0

at java.util.concurrent.FutureTask.report(FutureTask.java: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) at com.cloud.cloudreport.CloudReportApplication.run(CloudReportApplication.java:92) at org.springframework.boot.SpringApplication.callRunner(SpringApplication.java:776) at org.springframework.boot.SpringApplication.callRunners(SpringApplication.java:760) at org.springframework.boot.SpringApplication.afterRefresh(SpringApplication.java:747) at org.springframework.boot.SpringApplication.run(SpringApplication.java:315) at org.springframework.boot.SpringApplication.run(SpringApplication.java:1162) at org.springframework.boot.SpringApplication.run(SpringApplication.java:1151) at com.cloud.cloudreport.CloudReportApplication.main(CloudReportApplication.java:43) Caused by: org.springframework.dao.DataIntegrityViolationException: Prepa 在java.util.concurrent.FutureTask.report(FutureTask.java:122)在java.util.concurrent.FutureTask.get(FutureTask.java:192)在com.cloud.cloudreport.CloudReportApplication.lambda $ 1(CloudReportApplication.java: 94)在org.springframework.boot.SpringApplication.callRunner(SpringApplication.java:776)在com.cloud.cloudreport.CloudReportApplication.run(CloudReportApplication.java:92)在java.util.ArrayList.forEach(ArrayList.java:1249) )的org.springframework.boot.SpringApplication.callRunners(SpringApplication.java:760)的org.springframework.boot.SpringApplication.afterRefresh(SpringApplication.java:747)的org.springframework.boot.SpringApplication.run(SpringApplication.java: 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:Prepa redStatementCallback; redStatementCallback; SQL []; SQL []; ORA-01841: (full) year must be between -4713 and +9999, and not be 0 ; ORA-01841 :(完整)年份必须在-4713到+9999之间,并且不能为0; nested exception is java.sql.SQLDataException: ORA-01841: (full) year must be between -4713 and +9999, and not be 0 嵌套异常为java.sql.SQLDataException:ORA-01841 :(完整)年份必须在-4713和+9999之间,并且不能为0

at org.springframework.jdbc.support.SQLExceptionSubclassTranslator.doTranslate(SQLExceptionSubclassTranslator.java:82) at org.springframework.jdbc.support.AbstractFallbackSQLExceptionTranslator.translate(AbstractFallbackSQLExceptionTranslator.java:73) at org.springframework.jdbc.support.AbstractFallbackSQLExceptionTranslator.translate(AbstractFallbackSQLExceptionTranslator.java:81) at org.springframework.jdbc.core.JdbcTemplate.execute(JdbcTemplate.java:649) at org.springframework.jdbc.core.JdbcTemplate.query(JdbcTemplate.java:684) at org.springframework.jdbc.core.JdbcTemplate.query(JdbcTemplate.java:711) at org.springframework.jdbc.core.JdbcTemplate.query(JdbcTemplate.java:761) at org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate.queryForObject(NamedParameterJdbcTemplate.java:211) at com.cloud.cloudreport.dao.TransactionRespository.getTransactionResult(TransactionRespository.java:68) at com.cloud.cloudreport.dao.TransactionRespository$$FastClassBySpringCGLIB$$60dee75d 在org.springframework.jdbc.support.SQLExceptionSubclassTranslator.doTranslate(SQLExceptionSubclassTranslator.java:82)在org.springframework.jdbc.support.AbstractFallbackSQLExceptionTranslator.translate(AbstractFallbackSQLExceptionTranslator.java:73)在org.springframework.jdbc.support.AbstractFallbackSQLExceptionlator (AbstractFallbackSQLExceptionTranslator.java:81)在org.springframework.jdbc.core.JdbcTemplate.execute(JdbcTemplate.java:649)在org.springframework.jdbc.core.JdbcTemplate.query(JdbcTemplate.java:684)在org.springframework。 org.springframework.jdbc.core.JdbcTemplate.query(JdbcTemplate.java:761)的org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate.queryForObject(NamedParameterJdbcTemplate的jdbc.core.JdbcTemplate.query(JdbcTemplate.java:711) java:211)com.cloud.cloudreport.dao.TransactionRespository.getTransactionResult(TransactionRespository.java:68)at com.cloud.cloudreport.dao.TransactionRespository $$ FastClassBySpringCGLIB $$ 60dee75d .invoke() at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:204) at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:721) at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:157) at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:136) at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179) at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:656) at com.cloud.cloudreport.dao.TransactionRespository$$EnhancerBySpringCGLIB$$ca18ee4e.getTransactionResult() at com.cloud.cloudreport.CloudReportApplication.lambda$0(CloudReportApplication.java:76) at java.util.concurrent.FutureTask.run(FutureTask.java:266) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java: org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:204)上的.invoke().org.springframework.aop.framework.CglibAopProxy $ CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:721)上的.invoke(MethodProxy.java:204) org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:136)上的.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:157)在org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179) )的org.springframework.aop.framework.CglibAopProxy $ DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:656)com.cloud.cloudreport.dao.TransactionRespository $$ EnhancerBySpringCGLIB $$ ca18ee4e.getTransactionResult()在com.cloud.cloudApplication。 .lambda $ 0(CloudReportApplication.java:76)在java.util.concurrent.FutureTask.run(FutureTask.java:266)在java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java: 1142) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) at java.lang.Thread.run(Thread.java:745) Caused by: java.sql.SQLDataException: ORA-01841: (full) year must be between -4713 and +9999, and not be 0 1142)at java.util.concurrent.ThreadPoolExecutor $ Worker.run(ThreadPoolExecutor.java:617)at java.lang.Thread.run(Thread.java:745)原因:java.sql.SQLDataException:ORA-01841:(完整)年份必须在-4713和+9999之间,并且不能为0

at oracle.jdbc.driver.T4CTTIoer.processError(T4CTTIoer.java:450) at oracle.jdbc.driver.T4CTTIoer.processError(T4CTTIoer.java:399) at oracle.jdbc.driver.T4C8Oall.processError(T4C8Oall.java:1017) at oracle.jdbc.driver.T4CTTIfun.receive(T4CTTIfun.java:655) at oracle.jdbc.driver.T4CTTIfun.doRPC(T4CTTIfun.java:249) at oracle.jdbc.driver.T4C8Oall.doOALL(T4C8Oall.java:566) at oracle.jdbc.driver.T4CPreparedStatement.doOall8(T4CPreparedStatement.java:215) at oracle.jdbc.driver.T4CPreparedStatement.doOall8(T4CPreparedStatement.java:58) at oracle.jdbc.driver.T4CPreparedStatement.executeForDescribe(T4CPreparedStatement.java:776) at oracle.jdbc.driver.OracleStatement.executeMaybeDescribe(OracleStatement.java:897) at oracle.jdbc.driver.OracleStatement.doExecuteWithTimeout(OracleStatement.java:1034) at oracle.jdbc.driver.OraclePreparedStatement.executeInternal(OraclePreparedStatement.java:3820) at oracle.jdbc.driver.OraclePreparedStatement.executeQuery(OraclePreparedStatement.java:3867) at oracle.jdb 在oracle.jdbc.driver.T4CTTIoer.processError(T4CTTIoer.java:450)在oracle.jdbc.driver.T4CTTIoer.processError(T4CTTIoer.java:399)在oracle.jdbc.driver.T4C8Oall.processError(T4C8Oall.java:1017 )在oracle.jdbc.driver.T4CTTIfun.receive(T4CTTIfun.java:655)在oracle.jdbc.driver.T4CTTIfun.doRPC(T4CTTIfun.java:249)在oracle.jdbc.driver.T4C8Oall.doOALL(T4C8Oall.java: 566)在oracle.jdbc.driver.T4CPreparedStatement.doOall8(T4CPreparedStatement.java:215)在oracle.jdbc.driver.T4CPreparedStatement.java:215在oracle.jdbc.driver.T4CPreparedStatement.doOall8(T4CPreparedStatement.java:58)。 :776),位于oracle.jdbc.driver.OracleStatement.executeMaybeDescribe(OracleStatement.java:897),位于oracle.jdbc.driver.OracleStatement.doExecuteWithTimeout(OracleStatement.java:1034),位于oracle.jdbc.driver.OraclePreparedStatement.executeInternal(OraclePreparedStatement)。 oracle.jdbc.driver.OraclePreparedStatement.executeQuery(OraclePreparedStatement.java:3867)上的java:3820) c.driver.OraclePreparedStatementWrapper.executeQuery(OraclePreparedStatementWrapper.java:1502) at org.springframework.jdbc.core.JdbcTemplate$1.doInPreparedStatement(JdbcTemplate.java:692) at org.springframework.jdbc.core.JdbcTemplate.execute(JdbcTemplate.java:633) ... 18 more c.driver.OraclePreparedStatementWrapper.executeQuery(OraclePreparedStatementWrapper.java:1502)在org.springframework.jdbc.core.JdbcTemplate $ 1.doInPreparedStatement(JdbcTemplate.java:692)在org.springframework.jdbc.core.JdbcTemplate.execute(JdbTemplate :633)...还有18个

Are there any changes that i need to make to this in order to execute the method in 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;
        }


    }

getTransactionResult(...) has no synchronization whatsoever. getTransactionResult(...)没有任何同步。 The container can manage stuff but it is up to you to keep order. 容器可以管理东西,但要取决于您要保持秩序。 The container has no way to know what needs synchronization. 容器无法知道需要同步的内容。

You can make the method synchronized or follow this 您可以使方法同步或遵循此方法

synchronized method or use spring @transactional? 同步方法还是使用spring @transactional?

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM