转账案例(方法二):使用QueryRunner完成转账
/* 使用QueryRunner完成转账案例: update account set money=money-1000 where name='jack'; update account set money=money+1000 where name='rose'; --------------------------------------------------------------- QueryRunner类构造方法: QueryRunner() 空参数构造方法 调用update/query方法执行sql语句的时候需要传递Connection对象 QueryRunner(DataSource ds) 带连接池的构造方法 调用update/query方法执行sql语句的时候,不需要传递Connection对象 QueryRunner会自动的从连接池中获取Connection对象,执行sql语句 执行完毕会自动把Connection对象归还给连接池 注意: 想要操作事务,就必须使用空参数构造方法 */
package com.ccc.demo04transferAccount; import com.ccc.demo02Utils.C3P0UtilsXML; import org.apache.commons.dbutils.DbUtils; import org.apache.commons.dbutils.QueryRunner; import java.sql.Connection; import java.sql.SQLException; public class Demo02QueryRunner { public static void main(String[] args) { //1.创建QueryRunner对象 QueryRunner qr = new QueryRunner(); //2.使用C3P0连接池获取Connection对象 Connection conn = C3P0UtilsXML.getConnection(); //3.调用QueryRunner对象中的方法update,执行增删改的sql语句 try { //开启事务 conn.setAutoCommit(false); int row1 = qr.update(conn, "update account set money=money-? where name=?", 1000, "jack"); System.out.println(0/0); int row2 = qr.update(conn, "update account set money=money+1000 where name='rose'"); //5.处理结果 if(row1>0 && row2>0){ System.out.println("恭喜您,转账成功!"); //提交事务 conn.commit(); } } catch (Exception e) { //这儿使用的异常是Exception异常,因为上面有一个数学异常(0/0) e.printStackTrace(); System.out.println("对不起,转账失败!"); try { //回滚事务 conn.rollback(); } catch (SQLException e1) { e1.printStackTrace(); } }finally { //4.把Connection归还给连接池 DbUtils.closeQuietly(conn); } } }
注意:
//1.创建QueryRunner对象 QueryRunner qr = new QueryRunner();
使用的是无参的构造方法,为什么不用QueryRunner(DataSource ds) 带连接池的构造方法(有参的构造方法)呢?
转钱、收钱是同一个获取数据库连接对象connection,若使用了有参的构造方法,那么connection是在C3P0连接池里随意取的一个,这样肯定就出错了。
只要在执行sql语句之前,开启事务就行。
文章来源: https://blog.csdn.net/qq_45083975/article/details/90812765