Spring集成JDBC锁CannotAcquireLockException

问题描述

我观察到以下异常。这是错误还是预期?我应该处理这个异常吗?

使用的版本:spring-integration-jdbc:5.4.2 数据库:Oracle 12c 服务器:Tomcat 9

以下是 bean 的实例化方式。

@Bean
public DefaultLockRepository defaultLockRepository(@Value("${table.prefix}") String prefix,@Value("${distributed.lock.ttl}") int ttl) {
    DefaultLockRepository repository = new DefaultLockRepository(imexDataSource());
    repository.setPrefix(prefix);
    repository.setTimetoLive(ttl);
    return repository;
}

@Bean
public JdbcLockRegistry jdbcLockRegistry(LockRepository lockRepository) {
    return new JdbcLockRegistry(lockRepository);
}

以下是我使用 API 的方式

@Bean
@ConditionalOnProperty(value = "generic.cron.email.notification.enabled",matchIfMissing = false,havingValue = "true")
public MyService myService(SomeService someService) {
    return new MyService(){

        @Scheduled(cron="${generic.cron.email.notification.expression}")
        @Override
        public void sendEmailAlerts() {
            log.debug("Attempting lock.obtain");
            Lock lock = lockRegistry.obtain("EMAIL_ALERT");
            if(Objects.isNull(lock)){
                log.warn("Received null lock");
                return;
            }
            boolean locked = false;
            try {
                locked = lock.tryLock();
                if(locked){
                    log.debug("Obtained lock");
                    someService.doSomething();
                }else {
                    log.debug("Unable to obtain lock");
                }
            } finally {
                if(locked){
                    log.debug("Releasing lock");
                    lock.unlock();
                }
            }
        }
    };
}

引发了以下异常。请注意,这仅发生一次,并且不经常发生。请查看代码并建议是否应使用该 API。还请告诉我这是否是 API 的预期行为,我们必须处理并忽略它。

2021-03-08 04:30:00,127 ERROR o.s.s.s.TaskUtils$LoggingErrorHandler [scheduling-1] 计划任务中发生意外错误 org.springframework.dao.CannotAcquireLockException:无法在 532ee0eb-2d24-38af-823e-b5482c4e12f3 处锁定互斥锁;嵌套异常是 org.springframework.transaction.TransactionSystemException: JDBC commit Failed;嵌套异常是 java.sql.sqlException: ORA-00604: error occurred at recursive sql level 1 ORA-08177: 无法序列化此事务的访问

at org.springframework.integration.jdbc.lock.JdbcLockRegistry$JdbcLock.rethrowAsLockException(JdbcLockRegistry.java:169) ~[spring-integration-jdbc-5.4.2.jar:5.4.2]
at org.springframework.integration.jdbc.lock.JdbcLockRegistry$JdbcLock.tryLock(JdbcLockRegistry.java:234) ~[spring-integration-jdbc-5.4.2.jar:5.4.2]
at org.springframework.integration.jdbc.lock.JdbcLockRegistry$JdbcLock.tryLock(JdbcLockRegistry.java:203) ~[spring-integration-jdbc-5.4.2.jar:5.4.2]
at com.xxx.xxxx.xxxxxx.config.schedule.SchedulerConfig$2.sendEmailAlerts(SchedulerConfig.java:66) ~[classes/:1.0-SNAPSHOT]
at com.xxx.xxxx.xxxxxx.config.schedule.SchedulerConfig$2$$FastClassBySpringcglib$$ee291c17.invoke(<generated>) ~[classes/:1.0-SNAPSHOT]
at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:218) ~[spring-core-5.3.2.jar:5.3.2]
at org.springframework.aop.framework.cglibAopProxy$cglibMethodInvocation.invokeJoinpoint(cglibAopProxy.java:771) ~[spring-aop-5.3.2.jar:5.3.2]
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163) ~[spring-aop-5.3.2.jar:5.3.2]
at org.springframework.aop.framework.cglibAopProxy$cglibMethodInvocation.proceed(cglibAopProxy.java:749) ~[spring-aop-5.3.2.jar:5.3.2]
at net.bull.javamelody.MonitoringSpringInterceptor.invoke(MonitoringSpringInterceptor.java:76) ~[javamelody-core-1.86.0.jar:1.86.0]
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186) ~[spring-aop-5.3.2.jar:5.3.2]
at org.springframework.aop.framework.cglibAopProxy$cglibMethodInvocation.proceed(cglibAopProxy.java:749) ~[spring-aop-5.3.2.jar:5.3.2]
at org.springframework.aop.framework.cglibAopProxy$DynamicAdvisedInterceptor.intercept(cglibAopProxy.java:691) ~[spring-aop-5.3.2.jar:5.3.2]
at com.xxx.xxxx.xxxxxx.config.schedule.SchedulerConfig$2$$EnhancerBySpringcglib$$21e62e1f.sendEmailAlerts(<generated>) ~[classes/:1.0-SNAPSHOT]
at jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[?:?]
at jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[?:?]
at jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[?:?]
at java.lang.reflect.Method.invoke(Method.java:566) ~[?:?]
at org.springframework.scheduling.support.ScheduledMethodRunnable.run(ScheduledMethodRunnable.java:84) ~[spring-context-5.3.2.jar:5.3.2]
at org.springframework.scheduling.support.DelegatingErrorHandlingRunnable.run(DelegatingErrorHandlingRunnable.java:54) [spring-context-5.3.2.jar:5.3.2]
at org.springframework.scheduling.concurrent.ReschedulingRunnable.run(ReschedulingRunnable.java:95) [spring-context-5.3.2.jar:5.3.2]
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:515) [?:?]
at java.util.concurrent.FutureTask.run(FutureTask.java:264) [?:?]
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:304) [?:?]
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128) [?:?]
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628) [?:?]
at java.lang.Thread.run(Thread.java:834) [?:?]

Caused by: org.springframework.transaction.TransactionSystemException: JDBC commit Failed;嵌套异常是 java.sql.sqlException: ORA-00604: error occurred at recursive sql level 1 ORA-08177: 无法序列化此事务的访问

at org.springframework.jdbc.datasource.DataSourceTransactionManager.translateException(DataSourceTransactionManager.java:435) ~[spring-jdbc-5.3.2.jar:5.3.2]
at org.springframework.jdbc.datasource.DataSourceTransactionManager.doCommit(DataSourceTransactionManager.java:336) ~[spring-jdbc-5.3.2.jar:5.3.2]
at org.springframework.transaction.support.AbstractPlatformTransactionManager.processCommit(AbstractPlatformTransactionManager.java:743) ~[spring-tx-5.3.2.jar:5.3.2]
at org.springframework.transaction.support.AbstractPlatformTransactionManager.commit(AbstractPlatformTransactionManager.java:711) ~[spring-tx-5.3.2.jar:5.3.2]
at org.springframework.transaction.interceptor.TransactionAspectSupport.commitTransactionAfterReturning(TransactionAspectSupport.java:654) ~[spring-tx-5.3.2.jar:5.3.2]
at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:407) ~[spring-tx-5.3.2.jar:5.3.2]
at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:119) ~[spring-tx-5.3.2.jar:5.3.2]
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186) ~[spring-aop-5.3.2.jar:5.3.2]
at org.springframework.aop.framework.cglibAopProxy$cglibMethodInvocation.proceed(cglibAopProxy.java:749) ~[spring-aop-5.3.2.jar:5.3.2]
at org.springframework.aop.framework.cglibAopProxy$DynamicAdvisedInterceptor.intercept(cglibAopProxy.java:691) ~[spring-aop-5.3.2.jar:5.3.2]
at org.springframework.integration.jdbc.lock.DefaultLockRepository$$EnhancerBySpringcglib$$dd629987.acquire(<generated>) ~[spring-integration-jdbc-5.4.2.jar:5.4.2]
at org.springframework.integration.jdbc.lock.JdbcLockRegistry$JdbcLock.doLock(JdbcLockRegistry.java:240) ~[spring-integration-jdbc-5.4.2.jar:5.4.2]
at org.springframework.integration.jdbc.lock.JdbcLockRegistry$JdbcLock.tryLock(JdbcLockRegistry.java:221) ~[spring-integration-jdbc-5.4.2.jar:5.4.2]
... 25 more

Caused by: java.sql.sqlException: ORA-00604: error occurred at recursive sql level 1 ORA-08177: 无法序列化此事务的访问

at oracle.jdbc.driver.T4CTTIoer11.processError(T4CTTIoer11.java:494) ~[ojdbc8.jar:12.2.0.1.0]
at oracle.jdbc.driver.T4CTTIoer11.processError(T4CTTIoer11.java:441) ~[ojdbc8.jar:12.2.0.1.0]
at oracle.jdbc.driver.T4CTTIoer11.processError(T4CTTIoer11.java:436) ~[ojdbc8.jar:12.2.0.1.0]
at oracle.jdbc.driver.T4C7Ocommoncall.processError(T4C7Ocommoncall.java:86) ~[ojdbc8.jar:12.2.0.1.0]
at oracle.jdbc.driver.T4CTTIfun.receive(T4CTTIfun.java:623) ~[ojdbc8.jar:12.2.0.1.0]
at oracle.jdbc.driver.T4CTTIfun.doRPC(T4CTTIfun.java:252) ~[ojdbc8.jar:12.2.0.1.0]
at oracle.jdbc.driver.T4C7Ocommoncall.doOCOMMIT(T4C7Ocommoncall.java:72) ~[ojdbc8.jar:12.2.0.1.0]
at oracle.jdbc.driver.T4CConnection.doCommit(T4CConnection.java:961) ~[ojdbc8.jar:12.2.0.1.0]
at oracle.jdbc.driver.PhysicalConnection.commit(PhysicalConnection.java:1937) ~[ojdbc8.jar:12.2.0.1.0]
at oracle.jdbc.driver.PhysicalConnection.commit(PhysicalConnection.java:1942) ~[ojdbc8.jar:12.2.0.1.0]
at jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[?:?]
at jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[?:?]
at jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[?:?]
at java.lang.reflect.Method.invoke(Method.java:566) ~[?:?]
at org.apache.tomcat.jdbc.pool.ProxyConnection.invoke(ProxyConnection.java:126) ~[tomcat-jdbc.jar:?]
at org.apache.tomcat.jdbc.pool.JdbcInterceptor.invoke(JdbcInterceptor.java:108) ~[tomcat-jdbc.jar:?]
at org.apache.tomcat.jdbc.pool.interceptor.AbstractCreateStatementInterceptor.invoke(AbstractCreateStatementInterceptor.java:79) ~[tomcat-jdbc.jar:?]
at org.apache.tomcat.jdbc.pool.JdbcInterceptor.invoke(JdbcInterceptor.java:108) ~[tomcat-jdbc.jar:?]
at org.apache.tomcat.jdbc.pool.disposableConnectionFacade.invoke(disposableConnectionFacade.java:81) ~[tomcat-jdbc.jar:?]
at com.sun.proxy.$Proxy107.commit(UnkNown Source) ~[?:?]
at jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[?:?]
at jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[?:?]
at jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[?:?]
at java.lang.reflect.Method.invoke(Method.java:566) ~[?:?]
at net.bull.javamelody.JdbcWrapper$ConnectionInvocationHandler.invoke(JdbcWrapper.java:202) ~[javamelody-core-1.86.0.jar:1.86.0]
at net.bull.javamelody.JdbcWrapper$DelegatingInvocationHandler.invoke(JdbcWrapper.java:300) ~[javamelody-core-1.86.0.jar:1.86.0]
at com.sun.proxy.$Proxy108.commit(UnkNown Source) ~[?:?]
at org.springframework.jdbc.datasource.DataSourceTransactionManager.doCommit(DataSourceTransactionManager.java:333) ~[spring-jdbc-5.3.2.jar:5.3.2]
at org.springframework.transaction.support.AbstractPlatformTransactionManager.processCommit(AbstractPlatformTransactionManager.java:743) ~[spring-tx-5.3.2.jar:5.3.2]
at org.springframework.transaction.support.AbstractPlatformTransactionManager.commit(AbstractPlatformTransactionManager.java:711) ~[spring-tx-5.3.2.jar:5.3.2]
at org.springframework.transaction.interceptor.TransactionAspectSupport.commitTransactionAfterReturning(TransactionAspectSupport.java:654) ~[spring-tx-5.3.2.jar:5.3.2]
at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:407) ~[spring-tx-5.3.2.jar:5.3.2]
at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:119) ~[spring-tx-5.3.2.jar:5.3.2]
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186) ~[spring-aop-5.3.2.jar:5.3.2]
at org.springframework.aop.framework.cglibAopProxy$cglibMethodInvocation.proceed(cglibAopProxy.java:749) ~[spring-aop-5.3.2.jar:5.3.2]
at org.springframework.aop.framework.cglibAopProxy$DynamicAdvisedInterceptor.intercept(cglibAopProxy.java:691) ~[spring-aop-5.3.2.jar:5.3.2]
at org.springframework.integration.jdbc.lock.DefaultLockRepository$$EnhancerBySpringcglib$$dd629987.acquire(<generated>) ~[spring-integration-jdbc-5.4.2.jar:5.4.2]
at org.springframework.integration.jdbc.lock.JdbcLockRegistry$JdbcLock.doLock(JdbcLockRegistry.java:240) ~[spring-integration-jdbc-5.4.2.jar:5.4.2]
at org.springframework.integration.jdbc.lock.JdbcLockRegistry$JdbcLock.tryLock(JdbcLockRegistry.java:221) ~[spring-integration-jdbc-5.4.2.jar:5.4.2]
... 25 more

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)