数据库_jdbc_事务1

来源:互联网 发布:知白新书 编辑:程序博客网 时间:2024/05/01 15:42


JdbcUtils_bad位于utils包

package cn.itcast.utils;import java.io.InputStream;import java.sql.Connection;import java.sql.SQLException;import java.util.Properties;import javax.sql.DataSource;import org.apache.commons.dbcp.BasicDataSourceFactory;public class JdbcUtils_bad {//一个成员记住连接池private static DataSource ds;//静态代码块初始化一个DBCP连接池static{   try{            Properties prop = new Properties();            InputStream in = JdbcUtils_bad.class.getClassLoader().getResourceAsStream("dbcpconfig.properties");            prop.load(in);            BasicDataSourceFactory factory = new BasicDataSourceFactory();            ds = factory.createDataSource(prop);         }catch (Exception e) {            throw new ExceptionInInitializerError(e);         }   }   //如果关系到事务!不能将连接池传递给QueryRunner构造函数,   //而是在它update 或query时传个连接!   public static Connection getConnection() throws SQLException {      return ds.getConnection();   }}


AccountDao_bad位于dao包

package cn.itcast.dao;import java.sql.Connection;import org.apache.commons.dbutils.QueryRunner;import org.apache.commons.dbutils.handlers.BeanHandler;import cn.itcast.domain.Account;//DAO内部维护一个连接,构造时需传入一个连接,//并使用该连接进行CRUD(不优雅,实际开发中不使用!)public class AccountDao_bad {private Connection conn;//有参的构造函数最好配个无参的构造函数public AccountDao_bad() {super();}//不优雅!构造AccountDao的时候还要接收一个连接!所有CRUD操作都是在此连接上完成!//构造AccountDao的时候就接收一个连接!所有CRUD操作都是在此连接上完成!public AccountDao_bad(Connection conn) {this.conn=conn;}public void update(Account a){try{//因为事务如转帐,所以new QueryRunner的时候不能传它DataSource,//而要自己控制事务提交和关闭连接!QueryRunner runner = new QueryRunner();String sql = "update account set money=? where id=?";Object params[] = {a.getMoney(),a.getId()};//因为是处理事务,所以要自己控制连接的开启事务,提交事务runner.update(conn,sql, params);}catch (Exception e) {throw new RuntimeException(e);}}public Account find(int id){try{//因为事务如转帐,所以new QueryRunner的时候不能传它DataSource//而要自己控制事务提交和关闭连接!QueryRunner runner = new QueryRunner();String sql = "select * from account where id=?";//因为是处理事务,所以要自己控制连接的开启事务,提交事务return (Account) runner.query(conn,sql, id, new BeanHandler(Account.class));}catch (Exception e) {throw new RuntimeException(e);}}}/*//理论可行,开发不能用!DAO层不能处理业务,只提供CRUD//从a--->b帐户转100元,实际开发不能用!因为违背了3层架构DAO层应与Service解耦public void transfer() throws SQLException{Connection conn = null;try{conn = JdbcUtils.getConnection();         //在连接上开启事务         conn.setAutoCommit(false);         //因为转帐,所以new QueryRunner的时候不能传它DataSource,         //而是要自己事务提交后才关闭连接!         QueryRunner runner = new QueryRunner();         String sql1 = "update account set money=money-100 where name='aaa'";         runner.update(conn,sql1);         String sql2 = "update account set money=money+100 where name='bbb'";         runner.update(conn,sql2);         //提交事务         conn.commit();      }finally{         //最后将连接还给连接池         if(conn!=null){            conn.close();         }      }   }*/


AccountService_bad位于service包

package cn.itcast.service;import java.sql.Connection;import java.sql.SQLException;import org.junit.Test;import cn.itcast.dao.AccountDao_bad;import cn.itcast.domain.Account;import cn.itcast.utils.JdbcUtils_bad;public class AccountService_bad {/*这种管理事务的方法是:(不优雅,实际开发中不使用!) * 1,Service负责提供一个连接(从连接池中获取) * 2,Service负责开启这个连接上的事务 * 3,使用Dao完成业务的时候,将该连接传给Dao(作为构造时参数传进去) * DAO内部维护一个连接,构造时需传入一个连接接收, * 并使用该连接进行CRUD. * 4,Service控制该连接提交事务! */@Testpublic void test() throws SQLException{transfer1(1,2,50);}//业务之一:转帐功能//实际开发中,这种也不实用,也不优雅!哪有构造DAO的时候还传个连接进去的!//而实用的是用Spring或ThreadLocal绑定连接public void transfer1(int sourceid,int targetid,float money) throws SQLException{Connection conn = null;try {//自己从池中获得连接(记得自己释放)conn=JdbcUtils_bad.getConnection();//在连接上开启事务!conn.setAutoCommit(false);//重点在这句,指定连接conn传给DAO,让所有CRUD在此连接上完成!         //DAO内部维护一个连接,构造时需传入一个连接,         //并使用该连接进行CRUD(不优雅,实际开发中不使用!)         AccountDao_bad dao=new AccountDao_bad(conn);         //使用指定的连接(已开启事务的连接)处理下面4条SQL!         Account a = dao.find(sourceid);   //select语句1         Account b = dao.find(targetid);   //select语句2         a.setMoney(a.getMoney()-money);           b.setMoney(b.getMoney()+money);            dao.update(a); //update语句1         dao.update(b);//update语句2         conn.commit();      } finally{         //最后将连接还给连接池         if(conn!=null) conn.close();      }   }}


用到的第3方jar包

mysql-connector-java-5.0.8-bin.jar
commons-dbcp-1.2.2.jar
commons-pool.jar
commons-dbutils-1.2.jar

mysql -uroot -prootset character_set_client=gb2312;set character_set_results=gb2312;use day17;create table account(id int primary key auto_increment,name varchar(40),money float)character set utf8 collate utf8_general_ci;insert into account(name,money) values('林黛玉',1000);insert into account(name,money) values('薛宝钗',1000);insert into account(name,money) values('史湘云',1000); 


dbcpconfig.properties位于src目录

#连接设置driverClassName=com.mysql.jdbc.Driverurl=jdbc:mysql://localhost:3306/day17username=rootpassword=root#<!-- 初始化连接 -->initialSize=10#最大连接数量maxActive=50#<!-- 最大空闲连接 -->maxIdle=20#<!-- 最小空闲连接 -->minIdle=5#<!-- 超时等待时间以毫秒为单位 6000毫秒/1000等于60秒 即等1分钟后仍没连接,这时才告诉人家,呆会再来,暂无连接! -->maxWait=60000#JDBC驱动建立连接时附带的连接属性属性的格式必须为这样:[属性名=property;] #注意:"user" 与 "password" 两个属性会被明确地传递,因此这里不需要包含他们。connectionProperties=useUnicode=true;characterEncoding=utf8#指定由连接池所创建的连接的自动提交(auto-commit)状态。defaultAutoCommit=true#driver default 指定由连接池所创建的连接的只读(read-only)状态。#如果没有设置该值,则“setReadOnly”方法将不被调用。(某些驱动并不支持只读模式,如:Informix)defaultReadOnly=#driver default 指定由连接池所创建的连接的事务级别(TransactionIsolation)。#可用值为下列之一:(详情可见javadoc。)NONE,READ_UNCOMMITTED, READ_COMMITTED, REPEATABLE_READ, SERIALIZABLEdefaultTransactionIsolation=READ_COMMITTED










0 0
原创粉丝点击