Java程序中有一个线程和一个定时器,他们都会对数据库中的时间进行修改操作。有时可能会对同一条数据进行操作这样就出现了线程和定时器都处在阻塞状态了 没有任何反应了。请问如何才能避免这样造成的死锁问题呢?很急!
解决方案 »
- struts请求路径的问题
- spring的作用好处,面试的时候经常被问,大家都说说哪些内容
- struts2 URL中文参数
- rmi一个简单的练习: Exception in thread "main" java.lang.ClassCastException: $Proxy0(在线等~~~~~)
- JSP编译的.java 文件在 weblogic哪个目录中存放?在线等待!!!
- 求Tomcat+jsp/servlet的解决方案!!
- 请教在 window 2000 下面编译 jboss4.0 源文件生产可执行文件?
- 高手们,谁能把怎样配置TomCat总结一下,让我们这些新手上上路?
- 网站注册流程安全设计
- 读过Java核心技术的大牛们请进
- 用struts2上传文件得到文件路径
- myeclipse6.5中启动tomcat时出现ora-01017 Invalid username/password; logon denied
数据库本身是支持多线程并发访问,你所说的阻塞现象具体是什么?2个线程都在进行更新操作时等待?
如果你的代码很少,可以把代码放上来给大家分析。
同时提醒synchronized这样一种锁是满足某个条件下才可以有效的。
String sql = "update tb_msg_send set seqId=?,sendTime=?"
+ " where keyNum=?";//
try {
System.out.println("update keyNum:"+keyNum);
con = DBUtil.getConnection();
psmt = con.prepareStatement(sql, ResultSet.TYPE_SCROLL_INSENSITIVE,
ResultSet.CONCUR_READ_ONLY);
psmt.setString(1, seqId.trim());
psmt.setTimestamp(2, sendTime);
psmt.setString(3, keyNum.trim());
psmt.executeUpdate();
线程根据上面的seqID修改对应的msgId:
String sql = "update tb_msg_send set msgId=?" + " where seqId=?";//
try {
con = DBUtil.getConnection();
psmt = con.prepareStatement(sql, ResultSet.TYPE_SCROLL_INSENSITIVE,
ResultSet.CONCUR_READ_ONLY);
psmt.setString(1, msgId.trim());
psmt.setString(2, seqId.trim()); psmt.executeUpdate();
同时线程会执行下面操作,根据上面修改好的msgId修改sendSTATE 和returntime
String sql = "update tb_msg_send set sendState=?,returnTime=?"
+ " where msgId=?";//
try {
con = DBUtil.getConnection();
psmt = con.prepareStatement(sql, ResultSet.TYPE_SCROLL_INSENSITIVE,
ResultSet.CONCUR_READ_ONLY);
psmt.setString(1, sendState.trim());
psmt.setTimestamp(2, returnTime);
psmt.setString(3, msgId.trim()); psmt.executeUpdate();
需要说明的是:定时器和线程是不确定是否同时执行的,因为这两个线程一直在运行,按理说应该先执行定时器需要的操作,然后线程在按照顺序执行相应的修改。问题是这个线程什么时候进行操作时不确定的。也就是说线程要进行的操作即上面说的“线程根据上面的seqID修改对应的msgId:”这个操作有可能和“首先定时器执行的是下面代码,是根据主键修改对性的seqId和sendtime:”这个操作同时进行!所以我才怀疑是死锁的问题。反正就是在执行的时候突然程序就像停止一样没有任何反应了 本来方法中 都有sysout的输出的 但是一出现这个现象就什么都没有了!
为什么你的线程执行2个操作去拿了2次数据库连接?
建议每次在执行前输出aql语句,当发现程序停止时 直接拿输出的语句去mysql执行;看是否是数据库被锁产生的等待现象。
同时提醒mysql的InnoDB仅针对主键修改开启行级锁,其他修改默认都开启表级锁。
初步判定是你自己程序代码有问题,锁的问题应该是在数据库那边(也可能是数据库连接)。
经验啊经验~~~哎
public static Connection getConnection() {
Connection con = null;
try {
Class.forName(driver);
con = DriverManager.getConnection(url.trim()
+ "?useUnicode=true&characterEncoding=GBK&zeroDateTimeBehavior=convertToNull&transformedBitIsBoolean=true", uid, pwd);
} catch (Exception e) {
...... } return con;
}
closeDB();
}中将ResultSet、PreparedStatement和Connectio一次关闭了
closeDB方法代码如下:
try {
if (rs != null){
rs.close();
rs=null;
}
} catch (Exception e) {
e.printStackTrace();
}
try {
if (psmt != null)
{
psmt.close();
psmt=null;
}
} catch (Exception e) {
e.printStackTrace();
}
try {
if (con != null){
con.close();
con=null;
}
} catch (Exception e) {
e.printStackTrace();