数据库_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
- 数据库_jdbc_事务1
- 数据库_jdbc_事务2_ThreadLocal
- 数据库_jdbc_入门
- 数据库_jdbc_分页案例
- 数据库_jdbc_连接池
- 数据库_jdbc_改造MVC案例(登录注册)
- 数据库_jdbc_连接池(Tomcat创建)
- 数据库_JDBC_连接SQL Sever 常见Bug
- 数据库_jdbc_大数据(text+blob)_批处理
- 数据库_jdbc_调用存储过程+获取自动生成主键
- 数据库_jdbc_连接池+框架_改造分页案例
- 数据库事务1
- 数据库事务_笔记1
- 【事务一】数据库事务
- 数据库事务
- 数据库事务
- 数据库事务
- 数据库事务
- Ubuntu系统清理
- 通过在开发控制台操控变量理解backbone.js todo例子。
- Android平台下的加密算法之(RSA/DES/AES)
- android平台下lcd调试流程
- 手机站跳转代码(网站打开自动跳转到手机网站目录)
- 数据库_jdbc_事务1
- Hadoop学习笔记一 简要介绍
- repo source
- 几种常见模式识别算法整理和总结
- Spring AOP 常用的四种实现方式 - Spring之旅
- hibernate中criterion的常见用法
- 塞选字符
- MySQL存储过程例子,包含事务,参数,嵌套调用,游标,循环等
- 2013——自我反思