Could not retrieve transation read-only status server 的解決辦法
問題描述:
在專案開發的過程中,使用Hibernate的ORM進行建表時,出現 “ Could not retrieve transation read-only status server ”的異常,無法進行表的建立的操作,具體異常內容如下:
org.activiti.engine.ActivitiException: couldn't create db schema: create table ACT_GE_PROPERTY (
NAME_ varchar(64),
VALUE_ varchar(300),
REV_ integer,
primary key (NAME_)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE utf8_bin
at org.activiti.engine.impl.db.DbSqlSession.executeSchemaResource(DbSqlSession.java:1242)
at org.activiti.engine.impl.db.DbSqlSession.executeSchemaResource(DbSqlSession.java:1138)
at org.activiti.engine.impl.db.DbSqlSession.executeMandatorySchemaResource(DbSqlSession.java:897)
at org.activiti.engine.impl.db.DbSqlSession.dbSchemaCreateEngine(DbSqlSession.java:874)
at org.activiti.engine.impl.db.DbSqlSession.dbSchemaUpdate(DbSqlSession.java:952)
at org.activiti.engine.impl.db.DbSqlSession.performSchemaOperationsProcessEngineBuild(DbSqlSession.java:1318)
at org.activiti.engine.impl.SchemaOperationsProcessEngineBuild.execute(SchemaOperationsProcessEngineBuild.java:28)
at org.activiti.engine.impl.interceptor.CommandInvoker$1.run(CommandInvoker.java:37)
at org.activiti.engine.impl.interceptor.CommandInvoker.executeOperation(CommandInvoker.java:78)
at org.activiti.engine.impl.interceptor.CommandInvoker.executeOperations(CommandInvoker.java:57)
at org.activiti.engine.impl.interceptor.CommandInvoker.execute(CommandInvoker.java:42)
at org.activiti.engine.impl.interceptor.TransactionContextInterceptor.execute(TransactionContextInterceptor.java:48)
at org.activiti.engine.impl.interceptor.CommandContextInterceptor.execute(CommandContextInterceptor.java:63)
at org.activiti.engine.impl.interceptor.LogInterceptor.execute(LogInterceptor.java:35)
at org.activiti.engine.impl.cfg.CommandExecutorImpl.execute(CommandExecutorImpl.java:44)
at org.activiti.engine.impl.ProcessEngineImpl.<init>(ProcessEngineImpl.java:81)
at org.activiti.engine.impl.cfg.ProcessEngineConfigurationImpl.buildProcessEngine(ProcessEngineConfigurationImpl.java:665)
at etc.TActiviti.createActivitiTables(TActiviti.java:56)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:86)
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:459)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:675)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:382)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:192)
Caused by: java.sql.SQLException: Could not retrieve transation read-only status server
at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:1094)
at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:997)
at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:983)
at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:928)
at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:959)
at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:949)
at com.mysql.jdbc.ConnectionImpl.isReadOnly(ConnectionImpl.java:3967)
at com.mysql.jdbc.ConnectionImpl.isReadOnly(ConnectionImpl.java:3938)
at com.mysql.jdbc.StatementImpl.execute(StatementImpl.java:814)
at com.mysql.jdbc.StatementImpl.execute(StatementImpl.java:791)
at org.activiti.engine.impl.db.DbSqlSession.executeSchemaResource(DbSqlSession.java:1216)
... 40 more
Caused by: java.sql.SQLException: Unknown system variable 'tx_read_only'
at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:1094)
at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:4208)
at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:4140)
at com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:2597)
at com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java:2758)
at com.mysql.jdbc.ConnectionImpl.execSQL(ConnectionImpl.java:2820)
at com.mysql.jdbc.ConnectionImpl.execSQL(ConnectionImpl.java:2769)
at com.mysql.jdbc.StatementImpl.executeQuery(StatementImpl.java:1569)
at com.mysql.jdbc.ConnectionImpl.isReadOnly(ConnectionImpl.java:3961)
... 44 more
問題分析:
導致這個異常的情況有兩種:
一種情況為:使用MySql資料庫服務為最新版本8.0.11,而在專案開發的過程中使用了低版本的MySql驅動包。
二種情況為: 當MySQL的資料庫隔離級別為REPEATABLE-READ時,查詢一個select語句也算是事物的開始,而且在hibernate裡會把以select語句開頭的事務標記為只讀事務,此時在這個事務裡再執行insert、update、delete等DML語句就會出現如上的異常資訊。
解決方案:
解決方案一:
修改專案中MySQL資料庫驅動包,將版本選擇為與當前資料庫伺服器版本相同的版本,如果是Maven專案,則在pom.xml的配置檔案中,鍵入如下內容:
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>${mysql-connector-java.version}</version>
</dependency>
注意:${mysql-connector-java.version} 為自己匹配的版本號!!!
如果為普通Web專案,我這兒提供了幾個常用版本的MySQL驅動下載,點選下面連線進行下載:
https://download.csdn.net/download/hello_world_qwp/10473266
解決方案二:
通過修改MySQL的事務隔離級別實現,檢視當前MySQL資料庫的事務隔離級別,輸入命令 “ show variables like 'transaction_%'; ” ,如下圖:
將隔離級別修改為 -> READ-COMMITTED 即可,輸入命令 “ SET GLOBAL transaction_isolation='READ-COMMITTED'; ” 即可解決該問題了。
注:如果要永久的生效,則需要在MySQL的初始化配置檔案中進行配置,如下圖:
好了,關於 Could not retrieve transation read-only status server 的解決辦法 就寫到這兒了,如果還有什麼疑問或遇到什麼問題歡迎掃碼提問,也可以給我留言哦,我會一一詳細的解答的。