下面这段代码是完成把留言版的回复插入数据库的操作,里面涉及三条SQL语句:更新,插入,查询。前两条语句是一个整体必须同时被执行成功,所以我把它们做成一个事务,为了方便起见我把事务提交方法commit()放到最后一条查询语句后面,问题就出现了,我在前台页面用Ajax异步调用这个方法返回结果显示这个方法的所有SQL语句都执行成功,但是我查看数据库的表发现数据一点都没变,也就是这个方法返回的数据并没有提交到数据库,我把commit()放到第二条插入语句后面就成功了,我想问的是:
事务操作的commit()是不是不对应数据库的查询语言,最好能分析一下出现这种问题的原因。谢谢! //q_num:被回复的留言ID 
//reply:回复内容
public String insertReply(int q_num, String reply) {
Connection conn = null;
PreparedStatement ps = null;
ResultSet rs = null; try {
conn = DbUtils.getConn();//建立数据库连接
conn.setAutoCommit(false);
ps = conn
.prepareStatement("update msg_q set state='已读已回复' where id=?");//更新语句
ps.setInt(1, q_num);
ps.executeUpdate();
ps = conn
.prepareStatement("insert into msg_a(q_id,a_content)values(?,?)");//插入语句
ps.setInt(1, q_num);
ps.setString(2, reply);
ps.executeUpdate();
                           //在这里调用commit()能提交数据到数据库
conn.commit();
conn.setAutoCommit(true); ps = conn.prepareStatement("select a_date from msg_a where q_id=?");//查询语句
ps.setInt(1, q_num);
rs = ps.executeQuery();
if (rs.next()) {
return rs.getString("a_date");
}                           /*放在这个位置就不行,为什么?
                            conn.commit();
conn.setAutoCommit(true);*/ } catch (Exception ex) {
System.out.println("-->rollback()");
System.out.println(ex); try {
conn.rollback();
} catch (Exception e) {
System.out.println(e);
} return null;
} finally { DbUtils.close(rs, ps, conn);
}
return null;
}

解决方案 »

  1.   

    顺便再问一下:对于这种留言提交,除了把数据插入到数据库还要返回一些数据,比如说留言的时间,你们都是怎么设计的,是像我这样写三条语句还是把这三个语句写成一个SQL函数,或者直接不从数据库返回时间,用JS在前台生成一个时间?我觉得我这种代码有点多
      

  2.   

                               /*放在这个位置就不行,为什么?
                                conn.commit();
                conn.setAutoCommit(true);*/因为这2句放在这里没有被执行到
     return rs.getString("a_date");
    这句已经返回结果了,后面的语句就不执行了
      

  3.   

    1.
    ps = conn.prepareStatement("select a_date from msg_a where q_id=?");//查询语句
    这条查询语句的id是你前面数据库中插入的Id,所以必须要在前面写数据库过程结束后,才能正确执行这条查询操作。
    也就是说,一个写操作,一个读操作,要分开进行,要有先后顺寻。2.
    这个留言回复的时间需要在数据库保存的,所以我觉得还是应该从数据库返回这些数据。