场景:在数据库中分别建了两张表 A、B,A 用来存储从网上爬取到的 ip 和 port,然后测试,有效就存储在 B 表。现在,我写了一个定时任务,每 60 分钟爬取一次,并存储在 A 表,然后把有效的存在 B 表。针对 B 表也写了一个定时任务,每 1 分钟检查一次是否仍然有效,如果无效就删除,有效就从当前行删除,插入到最后一行,一直这样循环。但是现在遇到一个问题,针对 B 表的定时任务,在检测完 B 中原有的数据,包括从当前行删除并插入到最后一行的数据后,其他从 A 表存入 B 表的数据再也无法读取到,这是因为锁吗?初学数据库,不太了解这个,求助各位。
1 taogen 2019-10-31 00:44:54 +08:00 via Android 什么叫 “从 A 表存入 B 表的数据再也无法读取”? 到底是哪个表的操作失败?是读操作,还是写操作失败? |
![]() | 2 sumarker PRO ``` 如果无效就删除,有效就从当前行删除,插入到最后一行,一直这样循环 ``` 没看懂这个操作是啥意思 orz |
3 z7356995 2019-10-31 06:53:31 +08:00 via Android 为什么不用一张表,A 表一张就够了,有效无效只要一个标记位就行 |
![]() | 4 aaa5838769 2019-10-31 07:37:43 +08:00 via iPhone 你应该加个字段就解决了,还干嘛弄个表 |
5 sansanhehe 2019-10-31 07:42:08 +08:00 via Android 没有用事务包裹整个过程吗? MySQL 的默认隔离级别解决了不可重复读和幻读问题 |
![]() | 6 fortunezhang 2019-10-31 08:05:46 +08:00 我读了好 5、6 遍才明白你的操作。 从 B 表中的操作,每次都是 select * from table_b order by id asc limit 1。这样就能够保证每次都能拿到了。还有一个复杂的方法,就是你保留上一次被删除的 id,select * from table_b where id=(last_deleted_id +1 ) 这样也行。 |
7 native 2019-10-31 08:40:08 +08:00 via Android 锁一般在多线程高并发时候会用到,仔细检查代码。 |
8 laminux29 2019-10-31 08:54:46 +08:00 楼主要小心网监,毕竟牢饭不好吃。 |
9 chengcanmm77 2019-10-31 08:56:07 +08:00 应该是定时任务开了事务 |
10 Yano 2019-10-31 09:41:22 +08:00 我觉得吧,你一个 A 表就足够了。A 表增加一个字段,标识是否有效;最多再加一个字段,标识是否扫描标记过。 |
![]() | 11 ShangAliyun 2019-10-31 11:12:09 +08:00 你这个用途要注意安全,扫公网端口,大多目的都不是“合法”的,甚至及时合法都得放着,容易被误解甚至利用 |
12 getlost OP @taogen 比如 B 表中原有 5 条记录,一段时间后都失效了,定时任务查出后将 5 条记录都从 B 表中删除,但是 B 表中新存进去的记录查询不到(是从 A 表中取出后新插入的),但是我用 Navicat 看了 B 表的记录,新的记录已经存进去了,就是取不到。 |
13 getlost OP @sumarker 因为我发现每次取一条记录,都只能取到第一条,如果这一条不删除,后面的都取不到。我考虑过用 id+1 这个,但是因为有删除操作,所以 id 不是连续的,然后我就想到这个了,把当前记录删除并插入到最后,这样我就可以一直取到新的记录了。,刚学,还不太会用。 |
14 getlost OP @z7356995 但是这样就存在一个问题啊,大多 ip 都无效,无效的记录越来越多,所以我就给删了 |
15 getlost OP @aaa5838769 没想到这个,但是如果加个字段,这里面大多都是无效的,能用的 ip 很少,所以干脆删了 |
16 getlost OP @sansanhehe 还不会这个,我现在只会用类似 SELCTE INSERT 这种,我去查查你说的这个,谢谢啊 |
![]() | 17 sumarker PRO @getlost 其实比较简单的是你先处理,然后 把处理中的放内存里(如果太大可能导致内存堆满,但是可以分片),然后 再去操作数据库不是更好吗? |
18 getlost OP @fortunezhang 我试了一下,这样不行,B 中的记录删除完之后,新加入的记录还是取不到。 |
19 getlost OP @native 我开了两个进程,一个执行爬取任务,并存在 A 表,然后测试 ip,有效存入 B 表,无效删除。另一个一直循环检测 B 表 ip 是否还能用,无效就删除。但是问题出现了,B 表原有的 ip 过段时间都会失效,全部删除,从第一个进程存入 B 表的记录,第二个进程就拿不到数据了。 |