16 数据库事务
16.1 银行存款
#账户基本信息表 create table account ( accountid varchar(18) , #账号 balance double(10,2) #余额 )#存款表 create table inaccount( accountid varchar(18) , #账号 inbalance double(10,2) #存入余额 )向账户中存入100元: Insert into inaccount(accountid, inbalance) values(‘500612345’,100); Insert into account(accountid, balance) values(‘500612345’,100);
l 在数据库中,所谓事务是指作为单个逻辑工作单元执行的一系列操作 。
l 为确保数据库中数据的一致性,数据的操纵应当是离散的成组的逻辑单元:当它全部完成时,数据的一致性可以保持,而当这个单元中的一部分操作失败,整个事务应全部视为错误,所有从起始点以后的操作应全部回退到开始状态。
事务的操作:先定义开始一个事务,然后对数据作修改操作,这时如果提交(COMMIT),这些修改就永久地保存下来,如果回退(ROLLBACK),数据库管理系统将放弃您所作的所有修改而回到开始事务时的状态
l 事务的ACID属性
16.2JDBC 事务处理
l 事务处理:保证所有事务都作为一个工作单元来执行,即使出现了故障,都不能改变这种执行方式。当在一个事务中执行多个操作时,要么所有的事务都被提交(commit),要么整个事务回滚(rollback)到最初状态
l 在JDBC中,事务默认是自动提交的,每次执行一个SQL 语句时,如果执行成功,就会向数据库自动提交,而不能回滚
l 为了让多个 SQL 语句作为一个事务执行:
l 可以通过Connection的getAutoCommit()方法来获得当前事务的提交方式
16.3 事务处理:命令行实现
1 查看提交模式
select @@autocommit;
2 用begin,rollback,commit来实现 begin //开始一个事务
rollback //事务回滚
commit //提交事务
例如:
MySQL> begin;
mysql> insert into test values(9,'dd','dd');
mysql> commit;
3 直接用set来改变mysql的自动提交模式
MYSQL默认是自动提交的,也就是你提交一个QUERY,它就直接执行 set autocommit =0 禁止自动提交 set autocommit =1 开启自动提交, 来实现事务的处理。 *当你用 setautocommit =0 的时候,你以后所有的SQL都将做为事务处理,直
到你用commit确认或rollback结束。
* 注意:当你结束这个事务的同时也开启了个新的事务
16.4理解事务隔离级别
l 事务隔离级别(transaction isolationlevels):隔离级别就是对事务并发控制的四个等级。分为
1 串行化(SERIALIZABLE)
2 可重复读(REPEATABLE READ)
3 读已提交(READ COMMITED)
4 读未提交(READ UNCOMMITED)
17 批量处理---提高处理速度
l 当需要成批插入或者更新记录时。可以采用Java的批量更新机制,这一机制允许多条语句一次性提交给数据库批量处理。通常情况下比单独提交处理更有效率
l JDBC的批量处理语句包括下面两个方法:
l 通常我们会遇到两种批量执行SQL语句的情况:
测试:
/** * 测试批量保存 * statement * PReparedStatement*//** * 用Statement批量保存5000条记录 * mysql statement batch time=3047 //时间为3047 毫秒 */ @Test public void testStatementBatch() { Connection conn = null; Statement stmt = null; long time = System.currentTimeMillis(); //记录开始时间 conn = JDBCUtils.getConnection(); try { stmt = conn.createStatement(); for(int i=0;i<5000;i++) { String sql = "INSERT INTO b_user(id,NAME,PASSWord,age) VALUES(1,'t','t',1)"; stmt.addBatch(sql); //批量插入 } stmt.executeBatch(); // 执行批量处理语句 System.out.println("mysql statement batch time="+(System.currentTimeMillis()-time)); } catch (SQLException e) { e.printStackTrace(); } finally { JDBCUtils.closeResource(conn, stmt, null); } }
PreparedStatement:
/** * 用PreparedStatement批量保存5000条记录 * mysql preparedstatement batch time=3094 */ @Test public void testPreparedStatementBatch() { Connection conn = null; PreparedStatement pstmt = null; long time = System.currentTimeMillis(); conn = JDBCUtils.getConnection(); String sql = "INSERT INTO b_user(id,NAME,PASSWORD,age) VALUES(?,?,?,?)"; try { pstmt = conn.prepareStatement(sql); for(int i=0;i<5000;i++) { pstmt.setInt(1, 1); pstmt.setString(2, "t"); pstmt.setString(3, "t"); pstmt.setInt(4, 1); pstmt.addBatch(); } pstmt.executeBatch(); System.out.println("mysql preparedstatement batch time="+(System.currentTimeMillis()-time)); } catch (SQLException e) { e.printStackTrace(); } finally { JDBCUtils.closeResource(conn, pstmt, null); }}
18. MySQL BLOB 类型介绍
l MySQL中,BLOB是一个二进制大型对象,是一个可以存储大量数据的容器,它能容纳不同大小的数据。BLOB类型实际是个类型系列( TinyBlob、Blob、MediumBlob和LongBlob ),除了在存储的最大信息量上不同外,他们是等同的。
l MySQL的四种BLOB类型
l 实际使用中根据需要存入的数据大小定义不同的BLOB类型。需要注意的是:如果你存储的文件过大,数据库的性能会下降很多。
l 有4种TEXT类型:TINYTEXT、TEXT、MEDIUMTEXT和LONGTEXT。这些对应4种BLOB类型,有相同的最大长度和存储需求
例子:
/** * 保存带图片的数据 */ @Test public void saveImage() { Connection conn = null; PreparedStatement pstmt = null; conn = JDBCUtils.getConnection(); String sql = "INSERT INTO bt_user (NAME,headimage) VALUES(?,?)"; try { pstmt = conn.prepareStatement(sql); pstmt.setString(1, "tom"); InputStream inputStream = new FileInputStream("D://............mm.jpg"); pstmt.setBinaryStream(2, inputStream,inputStream.available()); //mysql实现了所有方法,但有些方法执行无法通过,没有真正的实现 pstmt.executeUpdate(); } catch (SQLException e) { e.printStackTrace(); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } }
/** * 读取数据库带图片的一条记录 */ @Test public void getImage() { Connection conn = null; Statement stmt = null; ResultSet rs = null; conn = JDBCUtils.getConnection(); try { stmt = conn.createStatement(); String sql = "select * from bt_user where id=1"; rs = stmt.executeQuery(sql); if(rs.next()) { Blob blob = rs.getBlob("headimage"); InputStream is = blob.getBinaryStream(); String path = "D://work//Workspaces//day14_jdbc//src//cn//itcast//mysql//bt//mm2.jpg"; OutputStream os = new FileOutputStream(path); byte[] buffer = new byte[1024]; int len = -1; while((len=is.read(buffer))!=-1) { os.write(buffer, 0, len); } //os.flush(); os.close();//close中有flush is.close(); } } catch (SQLException e) { e.printStackTrace(); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } finally { JDBCUtils.closeResource(conn, stmt, rs); } }
新闻热点
疑难解答