开发者社区> 问答> 正文

多线程并发数据库事务问题:报错

现在我在数据库有张表,里面有个字段是boolean类型的,表示某件事情做过没有,做过表示true,没做过表示false。

现在问题是,在java中做这个事情比较耗时,还不一定成功,做之前先去判断是否做过,但是在多线程下会遇到问题,就是这个事情是不能重复做的,但是会出现。问一下大牛们都是如何实现的。

我现在的一些方案:

1、加锁?感觉没用,除非级别提高到其他线程不能读取。

2、临时变量,做在代码里面

3、临时表,做之前更新,做完解开,如果做的时候gg,重启程序就sb了.

...

大神都出来给点意见

展开
收起
kun坤 2020-06-06 16:04:03 771 0
1 条回答
写回答
取消 提交回答
  • 你看我这样的方案行不,直接update xxxx set zuoguo = true where zuoguou = false and id = xxx,如果返回更新成功,则做,否则的话就不做,这样应该能够避免多线程。
    ######

    这个问题要分两个方面

    第一个方面是就算重复执行,用什么逻辑让后执行的那个知道已经执行过了,自动跳出

    第二个方面就是做并发控制,让多个线程不要做同一个事情。

    以上说的完全是两个层面的事情,第一个层面是要在数据库里做好约束,避免脏数据产生。第二个层面才是多线程并发的控制。

    最简单,且正确(但容易出问题)的方法是

    select for update xxxx

    select status from xxxx

    程序判断if status == false

    执行处理代码

    update status = true

    commit

    如果status == true

    直接commit

    ######http://my.oschina.net/visualgui823/blog/640320######

    我觉得最简单的执行方式是

    UPDATE tablename
    SET flag = true
    WHERE id = 'id' AND flag = false
    然后程序判断更新的数据库行数目,如果是0,表示别人已经完成了,如果是1,表示这次完成。

    这个解决方案类似于数据库的乐观锁并发控制

    ######分配数据给多线程的时候控制一下不就行了   ######

    不用DB控制,用redis之类的。

    ######不太清楚实际并发有多大。一般的并发,完全可以通过队列来处理,然后再录入数据库。不建议在数据库上面动刀子。######建议使用redis,里面可以做事务同步。######你说的这个问题,其实和设计缓存挺像的,FutureTask+Callable来设计 ######

    引用来自“乌龟壳”的评论

    这个问题要分两个方面

    第一个方面是就算重复执行,用什么逻辑让后执行的那个知道已经执行过了,自动跳出

    第二个方面就是做并发控制,让多个线程不要做同一个事情。

    以上说的完全是两个层面的事情,第一个层面是要在数据库里做好约束,避免脏数据产生。第二个层面才是多线程并发的控制。

    最简单,且正确(但容易出问题)的方法是

    select for update xxxx

    select status from xxxx

    程序判断if status == false

    执行处理代码

    update status = true

    commit

    如果status == true

    直接commit

    ######试试 redis
    2020-06-06 16:04:08
    赞同 展开评论 打赏
问答排行榜
最热
最新

相关电子书

更多
DTCC 2022大会集锦《云原生一站式数据库技术与实践》 立即下载
阿里云瑶池数据库精要2022版 立即下载
2022 DTCC-阿里云一站式数据库上云最佳实践 立即下载