代码改变世界

插入数据库报错

2023-02-09 13:53  ly772186472  阅读(54)  评论(0编辑  收藏  举报

 

我本人是通过代码层次解决了:  原本是循环插入到数据库, 现在是定义一个数组 然后都存入数组中 然后批量插入数据库; 这样性能上也有所提升

网上有2种主要说法

 

第一种

 

问题描述: java代码在开始事务后,先做了一个查询,再insert,此时会报: 
        java.sql.SQLException: could not retrieve transation read-only status server
 

解决过程: 

        查看mysql的事物隔离级别 SHOW VARIABLES LIKE '%iso%';

        返回结果: REPEATABLE-READ

 

        把这个改成:READ-COMMITTED 就好了: SET GLOBAL tx_isolation='READ-COMMITTED'; 

 (记得java重启应用,要永久生效的就改my.ini配置文件)

 

20191111注明:

      发现不管是在my.cnf里面添加

transaction_isolation = READ-COMMITTED   然后重启mysql

或者直接执行SET GLOBAL tx_isolation='READ-COMMITTED';

或者直接执行 

set global transaction isolation level read committed;

 然后用SHOW VARIABLES LIKE '%iso%';  再次查询发现还是2条

'transaction_isolation', 'REPEATABLE-READ'
'tx_isolation', 'REPEATABLE-READ'

 

所以我一直以为没有修改成功,但是后来发现如果用select @@global.tx_isolation;  来进行查询其实已经变成READ-COMMITTED 了,这种情况是不是就是修改成功了?后续还有没有read-only这个错误还要有待观察。

最后我只在my.cnf中设置了transaction_isolation = READ-COMMITTED    然后后续继续观察是否error日志中又read-only错误日志

 

还有就是每次用工具重新连接mysql 查询select @@tx_isolation;     都是 REPEATABLE-READ

如果执行了set session transaction isolation level read committed;
再查询  select @@tx_isolation;    就会变成READ-COMMITTED

但是关闭工具再连接Mysql又变回REPEATABLE-READ

 

网上查询描述如下,但是为什么每次当前会话和global都不一样,难道是工具自己设置的隔离级别问题?后面研究一下再看

1.查看当前会话隔离级别

   select @@tx_isolation;

2.查看系统当前隔离级别

select @@global.tx_isolation;

 问题分析:

        当数据库隔离级别为REPEATABLE-READ时,查询一个select语句也算是事物的开始,而且在hibernate里会把以select语句开头的事务标记为只读事务,此时在这个事务里再执行insert、update、delete等DML语句就会报错。

http://dev.mysql.com/doc/refman/5.6/en/server-system-variables.html#sysvar_tx_read_only

第二种

 

连接mysql数据库出现上述错误,由于mysql数据库与jdbc版本兼容问题导致,出现此错误时用的是mysql5.7.24;jdbc用的是5.1.47,改成最新的6.0.6就好了

测试环境上发现100个instance和249个case多次save会有时候卡在addInstance方法30几分钟

开始以为是上述read-only 错误导致的问题,按照上面的方法配置了READ-COMMITTED  jdbc改成最新的6.0.6  还是有这个问题

 

后来发现 AddInstance  方法有用到事务@Transactional  怀疑是这个问题,把这个注释掉就不会卡住30几分钟了(timeout=36000),到底为什么出现这个问题后续继续研究

@Override
//@Transactional(propagation = Propagation.REQUIRED,isolation = Isolation.READ_COMMITTED,timeout=36000,rollbackFor=Exception.class)
public JSONObject AddInstance(InstanceViewModel tinstanceView,String taskcode,String token) {