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調整時間戳精度

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