Request processing failed; nested exception is org.springframework.transaction.CannotCreate.......

本文详细记录了一次由于MySQL服务器时区配置不正确导致的Spring框架无法创建事务的异常情况,通过调整JDBC连接参数中的时区设置,成功解决了问题。
Type Exception Report

Message Request processing failed; nested exception is org.springframework.transaction.CannotCreateTransactionException: Could not open JDBC Connection for transaction; nested exception is java.sql.SQLException: Cannot create PoolableConnectionFactory (The server time zone value 'Öйú±ê׼ʱ¼ä' is unrecognized or represents more than one time zone. You must configure either the server or JDBC driver (via the serverTimezone configuration property) to use a more specifc time zone value if you want to utilize time zone support.)

Description The server encountered an unexpected condition that prevented it from fulfilling the request.

Exception

org.springframework.web.util.NestedServletException: Request processing failed; nested exception is org.springframework.transaction.CannotCreateTransactionException: Could not open JDBC Connection for transaction; nested exception is java.sql.SQLException: Cannot create PoolableConnectionFactory (The server time zone value 'Öйú±ê׼ʱ¼ä' is unrecognized or represents more than one time zone. You must configure either the server or JDBC driver (via the serverTimezone configuration property) to use a more specifc time zone value if you want to utilize time zone support.)
	org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1006)
	org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:890)
	javax.servlet.http.HttpServlet.service(HttpServlet.java:635)
	org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:875)
	javax.servlet.http.HttpServlet.service(HttpServlet.java:742)
	org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
Root Cause

org.springframework.transaction.CannotCreateTransactionException: Could not open JDBC Connection for transaction; nested exception is java.sql.SQLException: Cannot create PoolableConnectionFactory (The server time zone value 'Öйú±ê׼ʱ¼ä' is unrecognized or represents more than one time zone. You must configure either the server or JDBC driver (via the serverTimezone configuration property) to use a more specifc time zone value if you want to utilize time zone support.)
	org.springframework.jdbc.datasource.DataSourceTransactionManager.doBegin(DataSourceTransactionManager.java:305)
	org.springframework.transaction.support.AbstractPlatformTransactionManager.getTransaction(AbstractPlatformTransactionManager.java:378)
	org.springframework.transaction.interceptor.TransactionAspectSupport.createTransactionIfNecessary(TransactionAspectSupport.java:474)
	org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:289)
	org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:98)
	org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
	org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:212)
	com.sun.proxy.$Proxy22.findCustomerById(Unknown Source)
	com.lemonsun.controller.CustomerController.findCustomerById(CustomerController.java:19)
	java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	java.base/java.lang.reflect.Method.invoke(Method.java:564)
	org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:215)
	org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:142)
	org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:102)
	org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:895)
	org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:800)
	org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87)
	org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1038)
	org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:942)
	org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:998)
	org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:890)
	javax.servlet.http.HttpServlet.service(HttpServlet.java:635)
	org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:875)
	javax.servlet.http.HttpServlet.service(HttpServlet.java:742)
	org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
Root Cause

java.sql.SQLException: Cannot create PoolableConnectionFactory (The server time zone value 'Öйú±ê׼ʱ¼ä' is unrecognized or represents more than one time zone. You must configure either the server or JDBC driver (via the serverTimezone configuration property) to use a more specifc time zone value if you want to utilize time zone support.)
	org.apache.commons.dbcp2.BasicDataSource.createPoolableConnectionFactory(BasicDataSource.java:2385)
	org.apache.commons.dbcp2.BasicDataSource.createDataSource(BasicDataSource.java:2110)
	org.apache.commons.dbcp2.BasicDataSource.getConnection(BasicDataSource.java:1563)
	org.springframework.jdbc.datasource.DataSourceTransactionManager.doBegin(DataSourceTransactionManager.java:262)
	org.springframework.transaction.support.AbstractPlatformTransactionManager.getTransaction(AbstractPlatformTransactionManager.java:378)
	org.springframework.transaction.interceptor.TransactionAspectSupport.createTransactionIfNecessary(TransactionAspectSupport.java:474)
	org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:289)
	org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:98)
	org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
	org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:212)
	com.sun.proxy.$Proxy22.findCustomerById(Unknown Source)
	com.lemonsun.controller.CustomerController.findCustomerById(CustomerController.java:19)
	java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	java.base/java.lang.reflect.Method.invoke(Method.java:564)
	org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:215)
	org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:142)
	org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:102)
	org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:895)
	org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:800)
	org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87)
	org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1038)
	org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:942)
	org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:998)
	org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:890)
	javax.servlet.http.HttpServlet.service(HttpServlet.java:635)
	org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:875)
	javax.servlet.http.HttpServlet.service(HttpServlet.java:742)
	org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
Root Cause

java.sql.SQLException: The server time zone value 'Öйú±ê׼ʱ¼ä' is unrecognized or represents more than one time zone. You must configure either the server or JDBC driver (via the serverTimezone configuration property) to use a more specifc time zone value if you want to utilize time zone support.
	com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:129)
	com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:97)
	com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:89)
	com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:63)
	com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:73)
	com.mysql.cj.jdbc.exceptions.SQLExceptionsMapping.translateException(SQLExceptionsMapping.java:76)
	com.mysql.cj.jdbc.ConnectionImpl.createNewIO(ConnectionImpl.java:835)
	com.mysql.cj.jdbc.ConnectionImpl.<init>(ConnectionImpl.java:455)
	com.mysql.cj.jdbc.ConnectionImpl.getInstance(ConnectionImpl.java:240)
	com.mysql.cj.jdbc.NonRegisteringDriver.connect(NonRegisteringDriver.java:207)
	org.apache.commons.dbcp2.DriverConnectionFactory.createConnection(DriverConnectionFactory.java:53)
	org.apache.commons.dbcp2.PoolableConnectionFactory.makeObject(PoolableConnectionFactory.java:291)
	org.apache.commons.dbcp2.BasicDataSource.validateConnectionFactory(BasicDataSource.java:2395)
	org.apache.commons.dbcp2.BasicDataSource.createPoolableConnectionFactory(BasicDataSource.java:2381)
	org.apache.commons.dbcp2.BasicDataSource.createDataSource(BasicDataSource.java:2110)
	org.apache.commons.dbcp2.BasicDataSource.getConnection(BasicDataSource.java:1563)
	org.springframework.jdbc.datasource.DataSourceTransactionManager.doBegin(DataSourceTransactionManager.java:262)
	org.springframework.transaction.support.AbstractPlatformTransactionManager.getTransaction(AbstractPlatformTransactionManager.java:378)
	org.springframework.transaction.interceptor.TransactionAspectSupport.createTransactionIfNecessary(TransactionAspectSupport.java:474)
	org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:289)
	org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:98)
	org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
	org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:212)
	com.sun.proxy.$Proxy22.findCustomerById(Unknown Source)
	com.lemonsun.controller.CustomerController.findCustomerById(CustomerController.java:19)
	java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	java.base/java.lang.reflect.Method.invoke(Method.java:564)
	org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:215)
	org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:142)
	org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:102)
	org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:895)
	org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:800)
	org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87)
	org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1038)
	org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:942)
	org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:998)
	org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:890)
	javax.servlet.http.HttpServlet.service(HttpServlet.java:635)
	org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:875)
	javax.servlet.http.HttpServlet.service(HttpServlet.java:742)
	org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
Root Cause

com.mysql.cj.exceptions.InvalidConnectionAttributeException: The server time zone value 'Öйú±ê׼ʱ¼ä' is unrecognized or represents more than one time zone. You must configure either the server or JDBC driver (via the serverTimezone configuration property) to use a more specifc time zone value if you want to utilize time zone support.
	java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
	java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
	java.base/jdk.internal.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
	java.base/java.lang.reflect.Constructor.newInstance(Constructor.java:488)
	com.mysql.cj.exceptions.ExceptionFactory.createException(ExceptionFactory.java:61)
	com.mysql.cj.exceptions.ExceptionFactory.createException(ExceptionFactory.java:85)
	com.mysql.cj.util.TimeUtil.getCanonicalTimezone(TimeUtil.java:132)
	com.mysql.cj.protocol.a.NativeProtocol.configureTimezone(NativeProtocol.java:2234)
	com.mysql.cj.protocol.a.NativeProtocol.initServerSession(NativeProtocol.java:2258)
	com.mysql.cj.jdbc.ConnectionImpl.initializePropsFromServer(ConnectionImpl.java:1319)
	com.mysql.cj.jdbc.ConnectionImpl.connectOneTryOnly(ConnectionImpl.java:966)
	com.mysql.cj.jdbc.ConnectionImpl.createNewIO(ConnectionImpl.java:825)
	com.mysql.cj.jdbc.ConnectionImpl.<init>(ConnectionImpl.java:455)
	com.mysql.cj.jdbc.ConnectionImpl.getInstance(ConnectionImpl.java:240)
	com.mysql.cj.jdbc.NonRegisteringDriver.connect(NonRegisteringDriver.java:207)
	org.apache.commons.dbcp2.DriverConnectionFactory.createConnection(DriverConnectionFactory.java:53)
	org.apache.commons.dbcp2.PoolableConnectionFactory.makeObject(PoolableConnectionFactory.java:291)
	org.apache.commons.dbcp2.BasicDataSource.validateConnectionFactory(BasicDataSource.java:2395)
	org.apache.commons.dbcp2.BasicDataSource.createPoolableConnectionFactory(BasicDataSource.java:2381)
	org.apache.commons.dbcp2.BasicDataSource.createDataSource(BasicDataSource.java:2110)
	org.apache.commons.dbcp2.BasicDataSource.getConnection(BasicDataSource.java:1563)
	org.springframework.jdbc.datasource.DataSourceTransactionManager.doBegin(DataSourceTransactionManager.java:262)
	org.springframework.transaction.support.AbstractPlatformTransactionManager.getTransaction(AbstractPlatformTransactionManager.java:378)
	org.springframework.transaction.interceptor.TransactionAspectSupport.createTransactionIfNecessary(TransactionAspectSupport.java:474)
	org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:289)
	org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:98)
	org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
	org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:212)
	com.sun.proxy.$Proxy22.findCustomerById(Unknown Source)
	com.lemonsun.controller.CustomerController.findCustomerById(CustomerController.java:19)
	java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	java.base/java.lang.reflect.Method.invoke(Method.java:564)
	org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:215)
	org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:142)
	org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:102)
	org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:895)
	org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:800)
	org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87)
	org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1038)
	org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:942)
	org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:998)
	org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:890)
	javax.servlet.http.HttpServlet.service(HttpServlet.java:635)
	org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:875)
	javax.servlet.http.HttpServlet.service(HttpServlet.java:742)
	org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
Note The full stack trace of the root cause is available in the server logs.

解决:

jdbc.driver=com.mysql.cj.jdbc.Driver
jdbc.url=jdbc:mysql://127.0.0.1:3307/123?characterEncoding=utf8&serverTimezone=GMT%2B8&useSSL=false

 

### 关于 `CannotCreateTransactionException` 错误分析 当遇到 `org.springframework.transaction.CannotCreateTransactionException` 的异常时,通常表明应用程序无法打开数据库连接来执行事务操作。这种问题可能由多种原因引起,例如配置不正确、数据源不可用或底层数据库服务中断。 #### 数据源关闭的原因 如果使用的是 HikariCP 作为数据源管理器,则可能会因为以下原因之一导致数据源被意外关闭: - 应用程序上下文未正常初始化。 - 配置文件中的参数设置不当,例如最大池大小过低或超时时间不足[^1]。 - 数据库服务器宕机或者网络分区问题使得 HikariCP 认为连接已失效并主动销毁资源。 #### 解决方案概述 以下是针对该问题的一些常见解决方案: 1. **验证数据库状态** 确认目标数据库实例正在运行,并且可以从应用所在的主机访问它。可以尝试通过命令行工具或其他客户端测试连通性[^1]。 2. **调整 HikariCP 参数** 修改 `application.properties` 或者 `application.yml` 文件里的相关属性以优化性能表现以及增强鲁棒性。比如增加最小空闲连接数(`spring.datasource.hikari.minimum-idle`) 和延长等待获取新连接的时间 (`spring.datasource.hikari.connection-timeout`) 可能会有所帮助[^1]: ```properties spring.datasource.hikari.maximum-pool-size=10 spring.datasource.hikari.minimum-idle=5 spring.datasource.hikari.idle-timeout=300000 spring.datasource.hikari.connection-timeout=60000 ``` 3. **重新加载数据源 Bean** 如果怀疑是由于某些条件触发了数据源的自动关闭行为,可以在适当时候调用方法刷新当前使用的 DataSource 实例。这可以通过定义自定义逻辑实现,在必要情况下强制重建新的物理链接集合[^1]: ```java @Autowired private DataSource dataSource; public void resetDataSource() { if (dataSource instanceof HikariDataSource) { ((HikariDataSource)dataSource).close(); initializeDataSource(); // 假设这是另一个负责创建初始 DS 对象的方法 } } ``` 4. **监控健康状况** 利用 Spring Boot Actuator 提供的功能定期检查系统的整体运作情况,特别是有关 DB 连接的部分。这样可以帮助快速定位潜在隐患并采取预防措施避免未来再次发生类似事件. --- ### 示例代码片段展示如何动态切换/重置数据源 下面给出一段简单的 Java 示例演示怎样安全地处理这种情况下的恢复机制: ```java @Service public class DatabaseService { @Autowired private ApplicationContext context; /** * 当检测到现有数据源有问题时调用此函数修复环境. */ public synchronized void recoverFromBrokenConnection(){ try{ destroyCurrentDataSource(); recreateNewDataSourceInstance(); }catch(Exception e){ throw new RuntimeException("Failed to restore database connection",e); } } private void destroyCurrentDataSource(){ Map<String, Object> beans = context.getBeansWithAnnotation(Primary.class); for(Object bean : beans.values()){ if(bean instanceof DisposableBean && bean instanceof DataSource){ ((DisposableBean)bean).destroy(); } } } private void recreateNewDataSourceInstance(){ ConfigurableApplicationContext ctx = (ConfigurableApplicationContext)this.context; DefaultListableBeanFactory bf = (DefaultListableBeanFactory)ctx.getBeanFactory(); String[] names = bf.getBeanNamesForType(DataSource.class,true,false); for(String name : names){ bf.removeBeanDefinition(name); } JpaProperties jpaProps = this.context.getBean(JpaProperties.class); DatasourceProperties dsProps = this.context.getBean(DatasourceProperties.class); EmbeddedDatabaseBuilder builder = new EmbeddedDatabaseBuilder() .setType(dsProps.getType()) .setName(jpaProps.getName()); for(PropertyValue pv:jpaProps.getProperties().entrySet()){ builder.addScript((String)pv.getValue()); } DataSource renewedDS = builder.build(); bf.registerSingleton("primaryDataSource",renewedDS); } } ``` --- ###
评论 16
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值