场景:在数据库中分别建了两张表 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 2019-10-31 01:43:14 +08:00
```
如果无效就删除,有效就从当前行删除,插入到最后一行,一直这样循环 ``` 没看懂这个操作是啥意思 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 2019-10-31 12:42:58 +08:00
@getlost 其实比较简单的是你先处理,然后 把处理中的放内存里(如果太大可能导致内存堆满,但是可以分片),然后 再去操作数据库不是更好吗?
|
18
getlost OP @fortunezhang 我试了一下,这样不行,B 中的记录删除完之后,新加入的记录还是取不到。
|
19
getlost OP @native 我开了两个进程,一个执行爬取任务,并存在 A 表,然后测试 ip,有效存入 B 表,无效删除。另一个一直循环检测 B 表 ip 是否还能用,无效就删除。但是问题出现了,B 表原有的 ip 过段时间都会失效,全部删除,从第一个进程存入 B 表的记录,第二个进程就拿不到数据了。
|