4
回答
解决幻读较好的办法?
注册华为云得mate10,2.9折抢先购!>>>   

场景:

自己写了个小爬虫,主要是爬取某个小网站上的书籍信息。

(Spring JPA  +  mysql +……)

问题描述:

错误日志中发现大量的约束回滚异常。原因已经找出来了:

书籍有标签信息,多线程爬虫对标签的处理是:先查数据库有没有,没有则插入。

问题就出在这了。约束异常是因为我给标签加了唯一性约束。

线程A查询出数据库没有该标签,便向数据库插入该标签,但事务尚未提交;这个时候另一个线程B也插入了该标签并先一步提交了事务。

这个时候,线程A发现数据违反约束,只能回滚。

问题:

虽然我知道加个悲观锁的write_lock可以避免该问题,但悲观锁似乎是直接锁整张表。感觉性能应该会差很多。

对于这样的问题,有没有什么比较好的处理办法?(减少异常发生的次数且兼顾性能效率)

<无标签>
举报
itwriter
发帖于6个月前 4回/93阅

因为不了解整个的逻辑,因此只能根据你的表述,给出几个解决问题的思路:

1、多线程程序最好的就是处理的任务是完全隔离的,即:每个线程处理的任务都是唯一、明确、不重复的,所以在任务获取的时候,需要有一种分发机制来保证每个线程都可以获取到唯一明确的任务。

2、如果标签数据是可以重复,就是无法按照线程拆分的,则可以按照楼上的想法,标签数据使用另一个不带事务的连接去插入,当整个事务需要回滚的时候,去删除(删除的时候,需要考虑是否在此期间有其他的有相同标签的事务成功了,然后就不能删除了)

3、考虑使用一个临时标签表做,临时表里面的标签可以重复,然后定期合并到原来的标签表中

4、方法2的进化版,使用一个单独的模块来做,这个模块负责接收原子的指令:“新增标签XXX”、“新增标签YYY”、“删除标签XXX”,爬虫负责爬数据和调用标签模块的接口,标签模块负责对多线程发过来的请求进行处理(只要保证每个消息都处理了,就是最终一致性了,爬虫模块就不做标签重复的判断了。)

顶部