优化代码,想解决Duplicate enty key和OptimistickLockOperation问题,
出现了这个问题:
thread-1] INFO c.d.a.d.r.i.m.l.SyncLiveVideoVisitTimesByCityCodeMessageListener 44 - 资源按区县统计开始,资源类型是:LIVE_VIDEO,资源ID是:69052,访问者的IP为127.0.0.1
+++++++++++++++++++++++++++++dafda
2019-12-23 20:29:32.028 [] [pool-18-thread-1] ERROR c.d.f.m.provider.kafka.KafkaTopicMessageDispatcher 64 - message 5e00b210d08edbe4ae8742b0 is processed with error incorrect_query_for_execute_update (There is no English translation for this message.)
2019-12-23 20:29:32.028 [] [pool-18-thread-1] ERROR c.dzj.frw.mq.provider.kafka.MessageHandlerExecutor 64 - error to handle record with key=null in topic event-trace partition 0, cause:incorrect_query_for_execute_update (There is no English translation for this message.)
2019-12-23 20:29:32.028 [] [pool-18-thread-1] ERROR c.dzj.frw.mq.provider.kafka.MessageHandlerExecutor 69 - error message details
com.dzj.frw.mq.MQMessageException: java.lang.IllegalStateException: incorrect_query_for_execute_update (There is no English translation for this message.)
2019-12-23 20:27:19.374 [] [pool-18-thread-1] ERROR c.dzj.frw.mq.provider.kafka.MessageHandlerExecutor 69 - error message details
com.dzj.frw.mq.MQMessageException: java.lang.IllegalStateException: incorrect_query_for_execute_update (There is no English translation for this message.)
at com.dzj.frw.mq.provider.kafka.KafkaTopicMessageDispatcher.dispatchMessage(KafkaTopicMessageDispatcher.java:144)
at com.dzj.frw.mq.provider.kafka.MessageHandlerExecutor$MessageHandler.call(MessageHandlerExecutor.java:109)
at com.dzj.frw.mq.provider.kafka.MessageHandlerExecutor$MessageHandler.call(MessageHandlerExecutor.java:86)
at java.util.concurrent.FutureTask.run$$$capture(FutureTask.java:266)
at java.util.concurrent.FutureTask.run(FutureTask.java)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
at java.lang.Thread.run(Thread.java:748)
Caused by: java.lang.IllegalStateException: incorrect_query_for_execute_update (There is no English translation for this message.)
at org.eclipse.persistence.internal.jpa.QueryImpl.executeUpdate(QueryImpl.java:286)
at com.dzj.frw.bo.boql.BONativeQueryImpl.executeUpdate(BONativeQueryImpl.java:30)
at com.dzj.analytic.domain.resourcevisit.repository.jpa.JpaResourceAnalysisWithRegionRepository.set(JpaResourceAnalysisWithRegionRepository.java:59)
at com.dzj.analytic.domain.resourcevisit.servcie.ResourceAnalysisWithRegionService.increaseCountByRegion(ResourceAnalysisWithRegionService.java:70)
at com.dzj.analytic.domain.resourcevisit.servcie.ResourceAnalysisWithRegionService$$FastClassBySpringCGLIB$$46f6918b.invoke(<generated>)
at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:204)
解决办法:
把Nativesql接口调用由:
createNativeQuery(String sqlString,Class resultClass) ==》
createNativeQuery(String sqlString) 即可。
因为我的SQL是这样的:
insert into rtc.resource_count_by_region (
resource_id, resource_type, city_code,
latitude, longitude, total_count
)
values
(
'69052', 'LIVE_VIDEO', '310000', '31.235929',
'121.480539', '106'
) on duplicate key
update
latitude =
values
(latitude),
longitude =
values
(longitude),
total_count =
values
(total_count);
在代码中就是这样:
@Override
public ResourceAnalysisWithRegion set(ResourceAnalysisWithRegion analysis) {
StringBuilder boql = new StringBuilder("insert into rtc.resource_count_by_region (resource_id,resource_type,city_code,latitude,longitude,total_count) values");
boql.append(" (?,?,?,?,?,?) on duplicate key");
boql.append(" update total_count = values (total_count) ; ");
BONativeQuery nativeQuery = getDataAccessProxy().createNativeQuery(boql.toString(), ResourceAnalysisWithRegion.class);
nativeQuery.setParameter(1, analysis.getResourceId());
nativeQuery.setParameter(2, analysis.getResourceType().name());
nativeQuery.setParameter(3, analysis.getCityCode());
nativeQuery.setParameter(4, analysis.getLatitude());
nativeQuery.setParameter(5, analysis.getLongitude());
nativeQuery.setParameter(6, analysis.getTotalCount());
nativeQuery.setParameter(7, analysis.getTotalCount());
nativeQuery.executeUpdate();
return null;
}
以上代码的createNativeSql()导致出错,因为insert into 没有返回值,但是用了一个类来映射返回东西,所以报了这个错。
修改后如下:
StringBuilder boql = new StringBuilder("insert into rtc.resource_count_by_region (resource_id,resource_type,city_code,latitude,longitude,total_count) values");
boql.append(" (?,?,?,?,?,?) on duplicate key");
boql.append(" update total_count = values (total_count) ; ");
BONativeQuery nativeQuery = getDataAccessProxy().createNativeQuery(boql.toString());
搞定!
总结:解决问题方法多样,能解决问题就好。有的细节不必过于纠结。这个问题是想不出来的,要“猜”着尝试着解决。