我有一个多线的程序轮循去读数据库中的一张表叫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,但这样会造成锁,请问大家有什么好方法来做吗???
解决方案 »
- Mouse 与网格问题
- JAVASCRIPT在图片中取一个坐标点,鼠标点住左键拉伸一定区域,我想要得到这个点的坐标x,y值,还有拉伸一定区域的长,宽值。哪位js高手帮我看看怎么弄
- 根据IP获得客户端所在城市
- 请求前辈指点迷津
- 关于java跨网段关机问题
- 在JSP中用JDBC连接SQLSERVER2000的问题,大家都来讨论一下,应该比较有代表性
- ftp保存到本地的问题,好像还没有人问过
- 菜鸟的编译问题(使用的是JCreator)
- 奇怪问题!连接mysql为什么不用密码?
- 为什么我每次必须要加-classpath 才能编译执行JAVA程序,这样设置classpath 有错吗(如下)
- 菜鸟问题?
- HttpURLConnection必须收到应答才能成功通讯吗?
.....//程序代码
}
我的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为神六喝彩,向所有科技工作者致敬!
拒绝日货。