java mysql为什么会执行失败@?


注意啦,序列化为Json串后,Josn串是没有Long类型呢。而且反序列化回来如果也是Object接收,数字小于Interger最大值的话,给转成Integer啦!
newFixedThreadPool线程池的核心线程数是固定的,它使用了近乎于无界的LinkedBlockingQueue阻塞队列。当核心线程用完后,任务会入队到阻塞队列,如果任务执行的时间比较长,没有释放,会导致越来越多的任务堆积到阻塞队列,最后导致机器的内存使用不停的飙升,造成JVM OOM。

14. 直接大文件或者一次性从数据库读取太多数据到内存,可能导致OOM问题

如果一次性把大文件或者数据库太多数据达到内存,是会导致OOM的。所以,为什么查询DB数据库,一般都建议分批。

读取文件的话,一般文件不会太大,才使用Files.readAllLines()。为什么呢?因为它是直接把文件都读到内存的,预估下不会OOM才使用这个吧,可以看下它的源码:

如果是太大的文件,可以使用Files.line()按需读取,当时读取文件这些,一般是使用完需要关闭资源流的哈

15. 先查询,再更新/删除的并发一致性问题

在日常开发中,这种代码实现经常可见:先查询是否有剩余可用的票,再去更新票余量。

如果是并发执行,很可能有问题的,应该利用数据库更新/删除的原子性,正解如下:

日常业务开发中,我们经常跟事务打交道,事务失效主要有以下几个场景:

  • 底层数据库引擎不支持事务
  • 在非public修饰的方法使用
  • 异常被try...catch吃了,导致事务失效。

其中,最容易踩的坑就是后面两个,注解的事务方法给本类方法直接调用,伪代码如下:

如果用异常catch住,那事务也是会失效呢~,伪代码如下:

如果不通过反射,传入Integer.valueOf(100),走的是Integer重载。但是呢,反射不是根据入参类型确定方法重载的,而是以反射获取方法时传入的方法名称和参数类型来确定的,正解如下:

有更新语句的时候,timestamp可能会自动更新为当前时间,看个demo

我们可以发现c列是有CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,所以c列会随着记录更新而更新为当前时间。但是b列也会随着有记录更新为而更新为当前时间

之前我们对mysql数据库进行升级,新版本为8.0.12。但是升级完之后,发现now()函数,获取到的时间比北京时间晚8小时,原来是因为mysql8默认为美国那边的时间,需要指定时区

全局变量的SimpleDateFormat,在并发情况下,存在安全性问题。

又因为Calendar内部并没有线程安全机制,所以全局共享的SimpleDateFormat不是线性安全的。
}

最近一段时间,生产系统持续碰到一些数据库异常,致使 sql 执行失败。html

针对上面第一种状况,很容易从字面意义就得出是读取超时。然而查询资料 JDBC 存在多种 timeout,仔细研究了一下,梳理一下。spring

如下咱们从上之下分别了解这几种种超时时间。数据库

ConnectionTimeout :这个超时参数也是与 Socket 创建链接有关。若没有设置,一旦若是数据库相关地址参数错误错误,将会长时间阻塞在创建数据库链接上。app

使用网上一张图能够清晰的解析前三者关系。

实际上还存在操做系统层面上 Socket 超时。各个操做系统能够设置相应 Socket 超时时间,而后若 JDBC 没有设置,到了操做系统的超时时间也将会断开。可是咱们不能依赖该超时间,由于该时间彻底不可控,咱们应该显式设置。

刚开始碰到该异常,根据 CommunicationsException 查询一下了,大体都是说 Mysql server 端会检测空闲链接,超时后主动断开链接,致使客户端的链接失效。

那么什么是 mysql 的空闲链接那?简单来讲,mysql 链接进程 Command 为 sleep 状态。咱们可使用 show processlist ; 查看正在运行的进程。空闲的进程示例如图:

jdbc 链接会根据 mysql wait_timeout 检测空闲链接。若在 wait_timeout 时间内,链接仍是空闲状态,mysql server 将会断开这个连接。针对这种状况,采用编码模拟。 采用以下代码:

这个错误是发生在数据批量导入时。当时数据量大概 20 多W条,而后在批量插入时抛出该异常。如下为批量插入代码。

这段代码就是使用 ibatis batch 功能,批量插入数据。

查看代码注释可知,其目的就是为了设置一个状态值,这个状态值下面将用到。

此时咱们查看 executor.insert ,正常来讲该方法应该会执行sql 语句,而后插入数据库。可是查看源码你会发现,他最后调用的是 MappedStatement.sqlExecuteUpdate,进入方法刚开始就判断上文设置的 session batch 属性。固然这个属性,咱们刚开始已经设置成 true , 因此此时并无执行 sql 插入动做,而是将此次 sql 以及相关参数存储到内存。

Dubbo 调用,而后因为这个循环须要遍历 20 多 W 数据,这就致使该循环结束就须要半个多小时(假设一次 dubbo 调用耗时 10 ms),而咱们 mysql server wait_timeout 为 300s,因此 mysql server 提早主动释放空闲链接,而后等到真正执行批量插入时,就会致使上面的异常。


若是以为好的话,请帮做者点个赞呗~ 谢谢

喜欢本文的读者们,欢迎长按关注订阅号程序通事~让我与你分享程序那些事。

}

我要回帖

更多关于 mysql查看sql执行进度 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信