例如银行转账,涉及3条sql语句,其中一条是记录张三的转账次数,这就需要3条sql语句一起执行,才好做事务。
update user set money=money-100 where name='张三'
update user set money=money+100 where name='李四'
update temp set count=count+1 where name='张三'之前我都是用SQLServere2005的,我的做法是如下:Connection conn = DBUtilc3p0.getInstance().getConnection();
PreparedStatement ps = null;
try {
conn.setAutoCommit(false);
String sql="update user set money=money-? where name=? "
+"update user set money=money+? where name=? "
+"update temp set count=count+1 where name=? ";
ps = conn.prepareStatement(sql);
ps.setInt(1, 100);
ps.setString(2, "张三");
ps.setInt(3, 100);
ps.setString(4, "李四");
ps.setString(5, "张三");
ps.executeUpdate();
conn.commit();
} catch (SQLException e) {
e.printStackTrace();
try {
conn.rollback();
} catch (SQLException e1) {
e1.printStackTrace();
}
} finally {
closeAll(conn, ps, null);
}
以上代码执行正常,没有问题。我一直以来都是这么干的。我的问题是,我现在换成MySQL数据库,我发现MySQL的jdbc驱动不支持我上面这种写法,我把sql语句改成如下,语句间用;号隔开,还是不行,会报错。看来MySQL不允许一次执行多条sql语句。
String sql="update user set money=money-? where name=?;"
+"update user set money=money+? where name=?;"
+"update temp set count=count+1 where name=?;";我查了下,MySQL可能得用批处理才行,但是我发现用批处理的话我所知道的有如下两种方式,但都不合适我的需求
第一种:Statement ps=conn.createStatement();
ps.addBatch("update user set money=money-100 where name='张三'");
ps.addBatch("update user set money=money+100 where name='李四'");
ps.addBatch("update temp set count=count+1 where name='张三'");
ps.executeBatch();这个方式可行,但是可以发现,我用的是Statement,所以我的sql语句不灵活,没办法用?号来设置值。第二种:PreparedStatement ps=conn.prepareStatement("insert into temp values(?)");
ps.setInt(1, 100);
ps.addBatch();
ps.setInt(1, 200);
ps.addBatch();
ps.executeBatch();这个可以用?号来设置值,但是只能是同一条sql语句去设置不同的值,我的需求还有一条记录张三的转账次数的sql语句。mysql驱动是最新的。
到现在为止我还是找不到方法可以满足的我上面的需求,用SQLServer2005就没有这样的问题了,没办法,项目需要换MySQL,现在第一次碰到这种问题得请教大家了。
update user set money=money-100 where name='张三'
update user set money=money+100 where name='李四'
update temp set count=count+1 where name='张三'之前我都是用SQLServere2005的,我的做法是如下:Connection conn = DBUtilc3p0.getInstance().getConnection();
PreparedStatement ps = null;
try {
conn.setAutoCommit(false);
String sql="update user set money=money-? where name=? "
+"update user set money=money+? where name=? "
+"update temp set count=count+1 where name=? ";
ps = conn.prepareStatement(sql);
ps.setInt(1, 100);
ps.setString(2, "张三");
ps.setInt(3, 100);
ps.setString(4, "李四");
ps.setString(5, "张三");
ps.executeUpdate();
conn.commit();
} catch (SQLException e) {
e.printStackTrace();
try {
conn.rollback();
} catch (SQLException e1) {
e1.printStackTrace();
}
} finally {
closeAll(conn, ps, null);
}
以上代码执行正常,没有问题。我一直以来都是这么干的。我的问题是,我现在换成MySQL数据库,我发现MySQL的jdbc驱动不支持我上面这种写法,我把sql语句改成如下,语句间用;号隔开,还是不行,会报错。看来MySQL不允许一次执行多条sql语句。
String sql="update user set money=money-? where name=?;"
+"update user set money=money+? where name=?;"
+"update temp set count=count+1 where name=?;";我查了下,MySQL可能得用批处理才行,但是我发现用批处理的话我所知道的有如下两种方式,但都不合适我的需求
第一种:Statement ps=conn.createStatement();
ps.addBatch("update user set money=money-100 where name='张三'");
ps.addBatch("update user set money=money+100 where name='李四'");
ps.addBatch("update temp set count=count+1 where name='张三'");
ps.executeBatch();这个方式可行,但是可以发现,我用的是Statement,所以我的sql语句不灵活,没办法用?号来设置值。第二种:PreparedStatement ps=conn.prepareStatement("insert into temp values(?)");
ps.setInt(1, 100);
ps.addBatch();
ps.setInt(1, 200);
ps.addBatch();
ps.executeBatch();这个可以用?号来设置值,但是只能是同一条sql语句去设置不同的值,我的需求还有一条记录张三的转账次数的sql语句。mysql驱动是最新的。
到现在为止我还是找不到方法可以满足的我上面的需求,用SQLServer2005就没有这样的问题了,没办法,项目需要换MySQL,现在第一次碰到这种问题得请教大家了。
+"update user set money=money+? where name=?;"
+"update temp set count=count+1 where name=?;";这样试试可以不?
不过使用Spring管理事务,在一个事务中执行多条语句应该是可行的吧;
再次存储过程也是不错的选择的
这个方式可行,但是可以发现,我用的是Statement,所以我的sql语句不灵活,没办法用?号来设置值。用这种方式就好了,因为你的业务是这样的,所以也谈不上什么sql语句不灵活。个人意见
conn.setAutoCommit(false);
pst = con.prepareStatement(sql1);
pst.set......;
pst.executeUpdate();
pst = con.prepareStatement(sql2);
pst.set......;
pst.executeUpdate();
pst = con.prepareStatement(sql3);
pst.set......;
pst.executeUpdate();
conn.commit;
执行多次ps.executeUpdate()方法吗?
还有,谁说这样效率不好啊,只要你重新获取conn对象,效率是一样的
jdbc慢在建立连接上
pstat = con.prepareStatement("update userr set money=money-? where name=?");
pstat.setInt(1, 100);
pstat.setString(2, "李四");
pstat.executeUpdate();
pstat = con.prepareStatement("update userr set money=money+? where name=?");
pstat.setInt(1, 200);
pstat.setString(2, "张三");
pstat.executeUpdate();
pstat = con.prepareStatement("update temp set count=count+? where name=?");
pstat.setInt(1, 1);
pstat.setString(2, "张三");
pstat.executeUpdate();
con.commit();
PreparedStatement ps=conn.prepareStatement("update user set money = money-100 where name = ?");
ps.setString(1, "张三");
ps.addBatch();
ps=conn.prepareStatement("update user set money = money+100 where name = ?");
ps.setString(1, "李四");
ps.addBatch();
ps=conn.prepareStatement("update temp set count = count + 1 where name = ?");
ps.setString(1, "张三");
ps.addBatch();
ps.executeBatch();
试试看MySQL的连接字符串设置allowMultiQueries参数置为true,如:jdbc:mysql://xxxIp/xxxdb?user=root&password=&allowMultiQueries=true
你的sql试试;和下一条update语句空一个空隔看看
举一个例子:String sql = delete from annex where annexcode = ?;
String[] codes = {'aa','bb','cc'}
pst = cn.prepareStatement(sql);
for(int i=0;i<codes.length;i++){
pst.setString(1, codes[i]);
pst.addBatch();
}
pst.excuteBatch();
String sql="update user set money=money-? where name=? ;\n "
+"update user set money=money+? where name=? ;\n "
+"update temp set count=count+1 where name=? ;\n ";
分开执行,这段加上try...catch...,出现异常回滚事务就行了