我有一个多线的程序轮循去读数据库中的一张表叫task的表
task表中的记段为id
sms_body
try_times
是不断的在增加的
每个线程做如下步骤:
读一条TASK表中的记录
然后进过某些处理后把这条记录从TASK表中删除
如果处理中有错,那么把这条记录在task表中的try_times+1,连续+3次后表示失败,将它存入另一张TABLE里,然后在TASK表中将该记录删除,请问如果这样我怕有几个线程同时去读TASK表中的一条记录,如果是这样,就要在读时加SELECT FOR UPDATE,但这样会造成锁,请问大家有什么好方法来做吗???
task表中的记段为id
sms_body
try_times
是不断的在增加的
每个线程做如下步骤:
读一条TASK表中的记录
然后进过某些处理后把这条记录从TASK表中删除
如果处理中有错,那么把这条记录在task表中的try_times+1,连续+3次后表示失败,将它存入另一张TABLE里,然后在TASK表中将该记录删除,请问如果这样我怕有几个线程同时去读TASK表中的一条记录,如果是这样,就要在读时加SELECT FOR UPDATE,但这样会造成锁,请问大家有什么好方法来做吗???
.....//程序代码
}
我的email:[email protected]
在数据库里对于task表加锁。
以SQL server为例。事务开始:
执行select * from task(TABLOCK UPDLOCK)
锁定选项 UPDLOCK 表示 读取表时使用更新锁,而不使用共享锁,并将锁保留到语句或事务结束。UPDLOCK的有点是允许用户读取数据并在以后更新数据,同时确保自从上次读取数据后数据没有改变
TABLOCK表示将锁扩大到整个表
执行别的操作
执行delete from task where....
事务提交
这样比采用同步代码控制的好处是:首先适应性更好,不管对于数据库的操作是通过你的程序,还是直接用查询器,管理器,或别的程序操作,都能保证避免脏读。其次数据库在进行任何操作前,默认会加锁,所以你设置锁的操作没有额外的CPu开销,但是java里同步就需要了
坏处是:只能针对一种数据库,如果数据库换了,设置锁的命令也不一样了。
程序归程序还是不一样的。
使用
synchronized是不可少的!
比如说我们看到的很多用同步块 来 代替 同步方法 ,就是这个思想的表现。
对于楼上的程序来说,线程间的临界区是数据库中的这个表。所以对数据库的表操作加锁。可以将同步区域缩小到最小。也就是只有对数据库操作的几个SQL语句那么大。
就像使用同步块的函数不需要再声明为synchronized一样,当数据库的表操作同步后,调用这些操作的函数也不需要声明为同步,这就不需要java进行专门的同步支持,从而提高了效率。
如果你使用的数据库不一定是一种,以后可能要扩展。那你可以依靠java的同步支持 来实现对数据库表的同步。这样虽然比不上数据库上的同步,但是比起简单的给所有函数加上synchronized的方法好太多。
具体操作如下:
先声明一个Object tableObj。以后每次对于table进行事务操作的时候,都要先获得tableObj的锁
比如说
sychronized(tableObj)
{
//select * from table //alter the result
//delete from table
}
CSDN小助手是一款脱离浏览器也可以访问Csdn论坛的软件
界面:http://blog.csdn.net/Qqwwee_Com/archive/2005/10/16/504620.aspx
下载:http://szlawbook.com/csdnv2/csdnv2.rar为神六喝彩,向所有科技工作者致敬!
拒绝日货。