日期:2014-05-20  浏览次数:20624 次

Java 分布式并发问题【100分】
首先服务器结构是这样的。
  1,多台tomcat集群
  2,一台数据库服务器

现在问题是:
  网站上一个功能,点击的时候需要先查询这条数据的状态 如果状态为0那么就可以修改这条数据状态为1 如果状态是1 则不做操作 , 现在这条数据状态是0, 我开浏览器2个窗口 同时点击这一功能,正常的流程应该是 第一个请求 修改了状态为1, 第二个请求不做操作,但是结果是两个请求都修改了状态为1(根据输出SQL), 由于使用分布式,所以无法使用 同步锁 解决,请问有什么解决方案? 如果用什么技术解决?

------解决方案--------------------
探讨
首先服务器结构是这样的。
1,多台tomcat集群
2,一台数据库服务器

现在问题是:
网站上一个功能,点击的时候需要先查询这条数据的状态 如果状态为0那么就可以修改这条数据状态为1 如果状态是1 则不做操作 , 现在这条数据状态是0, 我开浏览器2个窗口 同时点击这一功能,正常的流程应该是 第一个请求 修改了状态为1, 第二个请求不做操作,但是结果是两个请求都修改了状态为……

------解决方案--------------------
贴出你的数据库版本,表结构

一般而言,查询状态的时候,用
SELECT ... FOR UPDATE WHERE ...
这个时候,不光突出状态,还把这条记录给锁住了,除了当前事务,其他事务无法读写该记录
继而更新
UPDATE ... SET XXX = 1 WHERE ....
然后COMMIT,放掉锁。其他事务才能读取,这个时候,读取的必然是更新后的状态。



------解决方案--------------------
探讨
引用:

引用:
(根据输出SQL)


看看你的SQL


SQL 是先SELECT 如果为0 则执行UPDATE (用if控制) , 也是就说第一个UPDATE还没执行完 第二个SELECT去查询 查到的也是0 所以 也执行了 UPDATE。

------解决方案--------------------
select for update
悲观锁
------解决方案--------------------
探讨
同一个事务或者程序很难解决分布式并发操作
数据库机制可以很好解决了。

谢谢。。。。


解决办法

1. 使用悲观锁 行级锁
2. 使用存储过程完成查询 修改操作