Mysql 时间戳未设置精度引发的血案

使用mysql少不了日期类型 平时直接用缺省的配置 没想到出现了修改完一条记录后记录数少一的情况…

客户端操作:修改一条数据
结果:原来有三条数据,修改一条变成了两条,点击搜索按钮 恢复三条
原因如下:
首先看日志:

Closing non transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@69be8ad6]
Creating a new SqlSession
SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@6c075c12] was not registered for synchronization because synchronization is not active
JDBC Connection [HikariProxyConnection@878728374 wrapping com.mysql.cj.jdbc.ConnectionImpl@2ba1987c] will not be managed by Spring
==>  Preparing: UPDATE door_ctrl_dev SET acsdevindexcode=?, acsdevname=?, acsdevtypedesc=?, acsdevtypecode=?, acsdevtypename=?, acsdevip=?, acsdevport=?, updatetime=?, dev_username=?, dev_password=?, remark=?, project_id=?, area_id=? WHERE deleted=0 AND acsdevindexcode = ? 
==> Parameters: 12w(String), 12wws122212(String), 12(String), 201926912(String), 门禁一体机(String), 21(String), 1(String), 2019-09-29 14:05:10.614(Timestamp), (String), (String), (String), a5a35309a4fc7445bfb6b687556c1943(String), 3022f53d6d81564919f2cf21d9a78778(String), 12w(String)
<==    Updates: 1
 Time:95 ms - ID:com.landsky.door.mapper.DoorCtrlDevMapper.update
Execute SQL:UPDATE door_ctrl_dev SET acsdevindexcode='12w', acsdevname='12wws122212', acsdevtypedesc='12', acsdevtypecode='201926912', acsdevtypename='门禁一体机', acsdevip='21', acsdevport='1', updatetime='2019-09-29 14:05:10.614', dev_username='', dev_password='', remark='', project_id='a5a35309a4fc7445bfb6b687556c1943', area_id='3022f53d6d81564919f2cf21d9a78778' WHERE deleted=0 AND acsdevindexcode = '12w'

Closing non transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@6c075c12]
Creating a new SqlSession
SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@168f45fa] was not registered for synchronization because synchronization is not active
JDBC Connection [HikariProxyConnection@335430570 wrapping com.mysql.cj.jdbc.ConnectionImpl@2ba1987c] will not be managed by Spring
 JsqlParserCountOptimize sql=SELECT  id,acsdevindexcode,acsdevname,acsdevtypedesc,acsdevtypecode,acsdevtypename,acsdevip,acsdevport,acsdevcode,regionindexcode,treatytype,createtime,updatetime,deleted,isonline,longitude,latitude,dev_username,dev_password,remark,project_id,area_id  FROM door_ctrl_dev 
 WHERE  deleted=0

AND project_id = ? AND area_id = ? AND updatetime BETWEEN ? AND ? AND createtime BETWEEN ? AND ?
==>  Preparing: SELECT COUNT(1) FROM door_ctrl_dev WHERE deleted = 0 AND project_id = ? AND area_id = ? AND updatetime BETWEEN ? AND ? AND createtime BETWEEN ? AND ? 
==> Parameters: a5a35309a4fc7445bfb6b687556c1943(String), 3022f53d6d81564919f2cf21d9a78778(String), 1970-01-01 08:00:00.0(Timestamp), 2019-09-29 14:05:10.749(Timestamp), 1970-01-01 08:00:00.0(Timestamp), 2019-09-29 14:05:10.749(Timestamp)
<==    Columns: COUNT(1)
<==        Row: 2
==>  Preparing: SELECT id,acsdevindexcode,acsdevname,acsdevtypedesc,acsdevtypecode,acsdevtypename,acsdevip,acsdevport,acsdevcode,regionindexcode,treatytype,createtime,updatetime,deleted,isonline,longitude,latitude,dev_username,dev_password,remark,project_id,area_id FROM door_ctrl_dev WHERE deleted=0 AND project_id = ? AND area_id = ? AND updatetime BETWEEN ? AND ? AND createtime BETWEEN ? AND ? LIMIT ?,? 
==> Parameters: a5a35309a4fc7445bfb6b687556c1943(String), 3022f53d6d81564919f2cf21d9a78778(String), 1970-01-01 08:00:00.0(Timestamp), 2019-09-29 14:05:10.749(Timestamp), 1970-01-01 08:00:00.0(Timestamp), 2019-09-29 14:05:10.749(Timestamp), 0(Long), 10(Long)
<==    Columns: id, acsdevindexcode, acsdevname, acsdevtypedesc, acsdevtypecode, acsdevtypename, acsdevip, acsdevport, acsdevcode, regionindexcode, treatytype, createtime, updatetime, deleted, isonline, longitude, latitude, dev_username, dev_password, remark, project_id, area_id
<==        Row: 139, 213, 12312, 123, 201926400, 双门控制器, 123, 2, null, null, null, 2019-09-29 13:35:44, 2019-09-29 13:35:44, 0, 0, null, null, , , , a5a35309a4fc7445bfb6b687556c1943, 3022f53d6d81564919f2cf21d9a78778
<==        Row: 140, w12w, 123, 12w, 201926656, 四门控制器, 1w1s1, 12, null, null, null, 2019-09-29 13:35:44, 2019-09-29 13:35:44, 0, 0, null, null, , , , a5a35309a4fc7445bfb6b687556c1943, 3022f53d6d81564919f2cf21d9a78778
<==      Total: 2
 Time:44 ms - ID:com.landsky.door.mapper.DoorCtrlDevMapper.selectPage
Execute SQL:SELECT id,acsdevindexcode,acsdevname,acsdevtypedesc,acsdevtypecode,acsdevtypename,acsdevip,acsdevport,acsdevcode,regionindexcode,treatytype,createtime,updatetime,deleted,isonline,longitude,latitude,dev_username,dev_password,remark,project_id,area_id FROM door_ctrl_dev WHERE deleted=0 AND project_id = 'a5a35309a4fc7445bfb6b687556c1943' AND area_id = '3022f53d6d81564919f2cf21d9a78778' AND updatetime BETWEEN '1970-01-01 08:00:00.0' AND '2019-09-29 14:05:10.749' AND createtime BETWEEN '1970-01-01 08:00:00.0' AND '2019-09-29 14:05:10.749' LIMIT 0,10

Closing non transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@168f45fa]
Creating a new SqlSession
SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@4a90de92] was not registered for synchronization because synchronization is not active
JDBC Connection [HikariProxyConnection@730998649 wrapping com.mysql.cj.jdbc.ConnectionImpl@2ba1987c] will not be managed by Spring
==>  Preparing: SELECT id,doorindexcode,doorname,doorno,acsdevindexcode,regionindexcode,channeltype,channelno,installlocation,remark,createtime,updatetime,deleted,isantictrl,ctrltype FROM door_ctrl_point WHERE deleted=0 AND acsdevindexcode IN (?,?) 
==> Parameters: 213(String), w12w(String)
<==      Total: 0
 Time:52 ms - ID:com.landsky.door.mapper.DoorCtrlPointMapper.selectList
Execute SQL:SELECT id,doorindexcode,doorname,doorno,acsdevindexcode,regionindexcode,channeltype,channelno,installlocation,remark,createtime,updatetime,deleted,isantictrl,ctrltype FROM door_ctrl_point WHERE deleted=0 AND acsdevindexcode IN ('213','w12w')

Closing non transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@4a90de92]

简单翻译下:
发生了一次update(影响1行) 一次select(结果两行,update之前为3行)
第一次update时候想把updateTime设置为2019-09-29 14:05:10.749 由于没有设置精度 进位成了2019-09-29 14:05:11
然后 在同一秒内 发生了select 想查询updateTime小于2019-09-29 14:05:10.749的记录 这自然是查不到的(不知道为什么查询时就不会进位了 可能是查询时不用写入?)

原因分析:
1.代码逻辑如果默认用了双边条件,即使不传入条件,也会加上1970年到now的时间范围(这其实不算大错…)
2.没设置时间戳精度,默认只到秒
解决方法:
1.设置3位精度
2.优化查询逻辑 不传入日期范围的情况下不滥用between and 而是用单边条件或者不用
两种方案任选即可 结合最好

PS:精度就是下面这个东西:
Navicat调整时间戳精度

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章