事务

JDBC JDBC JDBC 中使用 Transaction Transaction Transaction 编程(事务编程)

1. 1. 1. 事务是具备以下特征 (ACID)(ACID) (ACID) 的工作单元:

原子性(Atomicity —— 如果因故障而中断,则所有结果均被撤消;

一致性(Consistency —— 事务的结果保留不变;

隔离性( Isolation —— 中间状态对其它事务是不可见的;

持久性( Durability —— 已完成的事务结果上持久的。

原子操作,也就是不可分割的操作,必须一起成功一起失败。

2. 2. 2. 事务处理三步曲:(事务是一个边界)

connection.setAutoCommit(false); connection.setAutoCommit(false);connection.setAutoCommit(false); // 把自动提交关闭

②正常的 DBDBDB 操作 // 若有一条 SQL SQL SQL 语句失败了,自动回滚

connection.commit() connection.commit() connection.commit() // 主动提交

connection.rollback() connection.rollback() connection.rollback()// 主动回滚www.tarena.com.cn

8

3. 3. 3. JDBC JDBC JDBC 事务并发产生的问题和事务隔离级别

JDBC 事务并发产生的问题 :

①脏读( D irty R ead s )一个事务读取了另一个并行事务还未提交的数据。

②不可重复读( UnPrpeatable Read )一个事务再次读取之前的数据时,得到的数据不一

致,被另一个已提交的事务修改。

③幻读( P hantom Read )一个事务重新执行一个查询,返回的记录中包含了因为其它最

近提交的事务而产生的新记录。

为了避免以上三种情况的出现,则采用

事务隔离级别 :

以上的五个事务隔离级别都是在 ConnectionConnection Connection 类中定义的静态常量,使用

setTransactionIsolation(intsetTransactionIsolation(int setTransactionIsolation(int level) level) level) 方法可以设置事务隔离级别。

比如: con.setTransactionIsolation(Connection.con.setTransactionIsolation(Connection. con.setTransactionIsolation(Connection.TRANSACTION_READ_UNCOMMITTED );););

完整的代码片段:

try{ try{ try{

con.setAutoCommit(false) con.setAutoCommit(false)con.setAutoCommit(false) ; ; ; // step step step ①把自动提交关闭

Statement Statement Statement stmstmstm = == con.createStatement(); con.createStatement(); con.createStatement();

stm.executeUpdate("insertstm.executeUpdate("insert stm.executeUpdate("insert into into intoperson(id, person(id, person(id, name, name, name, age) age) age) values(520,values(520, values(520, 'X-Man', 'X-Man', 'X-Man', 18)"); 18)");18)");

stm.executeUpdate("insertstm.executeUpdate("insert stm.executeUpdate("insert into into intoPerson(id, Person(id, Person(id, name, name, name, age) age) age) values(521,values(521, values(521, 'Super', 'Super', 'Super', 19)"); 19)");19)");

// step step step ②正常的 DBDBDB 操作

con.commit(); con.commit(); con.commit();// step step step ③成功主动提交

} } } catch(SQLException catch(SQLExceptioncatch(SQLException e){ e){ e){

try{ try{ try{

con.rollback(); con.rollback();con.rollback();

} } } catch(Exception catch(Exceptioncatch(Exception e){ e){ e){ e.printStackTrace(); e.printStackTrace();e.printStackTrace(); } } } // step step step ③′失败则主动回滚

} } }

TRANSACTION_NONE TRANSACTION_NONETRANSACTION_NONE 不使用事务

TRANSACTION_READ_UNCOMMITTEDTRANSACTION_READ_UNCOMMITTED TRANSACTION_READ_UNCOMMITTED 可以读取未提交数据

TRANSACTION_READ_COMMITTEDTRANSACTION_READ_COMMITTED TRANSACTION_READ_COMMITTED

可以避免脏读,不能够读取没提交的数据,

最常用的隔离级别大部分数据库的默认

隔离级别

TRANSACTION_REPEATABLE_READTRANSACTION_REPEATABLE_READ TRANSACTION_REPEATABLE_READ 可以避免脏读,重复读取

TRANSACTION_SERIALIZABLETRANSACTION_SERIALIZABLE TRANSACTION_SERIALIZABLE 可以避免脏读,重复读取和幻读,(事务串

行化)会降低数据库效率www.tarena.com.cn

9

六、 JavaBean JavaBean JavaBean 定义

1 、是一个普通的 Java 类;

2 、在结构上没有预先的规定,不需要容器;

3 、要求放在包中,要求实现java.io.Serializalbe 接口

4 、要求有一个无参的构造方法;

5 、属性的类型必须保持唯一,返回值必须和set 方法参数类型一致

6 、对每个属性要有对应的 get set 方法。注:隐藏属性可以没有。

另外, POJO JavaBean 的区别:

POJO —— P ure O ld J ava Object or P lain O rdinary J ava O bject (简单 Java 类对象)

POJO 原则上不鼓励在 JavaBean 里面写业务逻辑方法。简单说POJO 除了能赋值,也

就是提供 get/set 方法,别的什么也不能做,它就好比一个水杯 , 不是个能烧水的水壶,因为

它没有烧水 () 这个方法,因此只能盛水。 POJO 主要用来和数据库里的表进行对应。

七、 JDBC2.0 JDBC2.0 JDBC2.0 新特性:

1 1 1 ScrollabilityScrollability Scrollability 可滚动结果集(可双向滚动),这种结果集不但可以双向滚动,相对定位,

绝对定位,并且可以修改数据信息。

滚动:可支持双向绝对与双向相对滚动,对结果集可进行多次迭代。

con.createStatement(ResultSet.TYPE_SCROLL_con.createStatement(ResultSet.TYPE_SCROLL_con.createStatement(ResultSet.TYPE_SCROLL_ IN IN IN SENSITIVE, SENSITIVE,SENSITIVE,

ResultSet.CONCUR_UPDATABLE);ResultSet.CONCUR_UPDATABLE); ResultSet.CONCUR_UPDATABLE);

TYPE_FORWARD_ONLY TYPE_FORWARD_ONLYTYPE_FORWARD_ONLY

该常量指示指针只能向前移动的 ResultSet ResultSet ResultSet 对象的类型。

TYPE_SCROLL_INSENSITIVETYPE_SCROLL_INSENSITIVE TYPE_SCROLL_INSENSITIVE :

该常量指示可滚动但通常不受其他的更改影响的ResultSet ResultSet ResultSet 对象的类型。

TYPE_SCROLL_SENSITIVE TYPE_SCROLL_SENSITIVETYPE_SCROLL_SENSITIVE :

该常量指示可以更新的 ResultSet ResultSet ResultSet 对象的并发模式。

滚动特性,对 ResultSet ResultSet ResultSet 调用:

绝对定位: boolean absolute(int row)

可以使用此方法跳到指定的记录位置。定位成功返回 true ,不成功返回 false false false ,若

返回值为 false false false ,则游标不会移动。

void afterLast() ,游标跳到最后一条记录之后。

void beforeFirst() ,游标跳到第一条记录之前。(跳到游标初始位)

相对定位: b oolean first() ,游标指向第一条记录。

b oolean last() ,游标指向最后一条记录。

b oolean next() ,此方法是使游标向下一条记录移动。

b oolean previous() ,可以使游标向上一条记录移动,前提是未到首条记录。www.tarena.com.cn

10

2 Updatability 结果集可更新。 ( 主要应用于桌面应用 )

ResultSet ResultSet ResultSet 结果集中,先使用moveToInsertRow() moveToInsertRow() moveToInsertRow() ,然后可以使用updateXxx(int updateXxx(int updateXxx(int

column, column, column, columnTypecolumnType columnType value) value) value) 方法来更新指定列数据,再使用insertRow() insertRow() insertRow() 方法插入记录,

最后将游标指回原位: moveToCurrentRow() moveToCurrentRow() moveToCurrentRow()

更新: rs.updateInt(1, 13800 ); // 修改

rs.deleteRow(); // 删除

rs.updateRow();

注:只有在必要的时候(如桌面应用)才用结果集更新数据库,因为使用结果集更新数

据库效率低下。可更新结果集还要看数据库驱动程序是否支持,如 Oracle 支持,而 MyS QL

就不支持。并且只能针对一张表做结果集更新。而且不能有 join 操作。必须有主键,必须

把所有非空且没有默认值的字段查出。处理可更新结果集时不能用 select * 来执行查询语

句,必须指出具体要查询的字段。

能否使用可更新结果集,要看使用的数据库驱动是否支持,还有只能用于单表且表中有

主键字段(可能会是联合主键),不能够有表连接,会取所有非空字段且没有默认值。

总之,能否使用 JDBC2.0 JDBC2.0 JDBC2.0 ResultSet ResultSet ResultSet 的新特性要看数据库驱动程序是否支持。

3 Batch updates 可批量更新

将一组对数据库的更新操作发送到数据库统一执行(数据库支持并发执行操作),以提

高效率。主要是通过减少数据( SQL 语句或参数)在网络上传输的次数来节省时间。

1 )对于 Statement Statement Statement 的批量更新处理:

stm. addBatch(String sql 1 ) ; 方法会在批处理缓存中加入一条 sql sql sql 语句。

stm.addBatch(String sql2);

int[] results = stm. executeBatch() ,执行批处理缓存中的所有sql sql sql 语句。

2 )对于 PreparedStatement PreparedStatement PreparedStatement 的批量更新处理:

pstm.setInt(1, 11);

pstm.setString(2, ” haha ” ); …

pstm. addBatch() 将一组参数添加到此PreparedStatement PreparedStatement PreparedStatement 对象的批处理命令中。

int[] results = pstm. executeBatch() 将一批命令提交给数据库来执行,如果全部命令

执行成功,则返回更新计数组成的数组。

注意 : : :

int[] 中每一个数表示该 SQL 语句所影响的记录条数。

PreparedStatement PreparedStatementPreparedStatement 中使用批量更新时,要先设置好参数后使用addBatch() addBatch() addBatch() 方法加入

缓存。

批量更新中只能使用更新或插入语句www.tarena.com.cn

11

八、 SQL3.0 SQL3.0 SQL3.0 规范中的新类型

Array Array Array 数组类型,主要用于保存一些类似于数组结构的数据。

Sturct Sturct Sturct 结构

Blob Blob Blob 大的二进制数据文件,最多存储 4G

Clob Clob Clob 大文本文件对象,最多存储 4G

在使用上述大对象的时候,在使用 JDBC 插入记录时要先插入一个空的占位对象,然后使用

select blobdata from t_blob where id =" + id + " for update 这样的语法来对获得的大对

象,进行实际的写入操作 Blo b 通过 getBinaryOutputStream() 方法获取流进行写入。

getBinaryStream() 方法获得流来获取 Blob 中存储的数据。

C lob 的操作也和 B lob 相同。getAsciiStream() 方法用于读取存储的文本对象,

getAsciiOutputStream() 方法获得流用来向文件对象写入的。

BLOB CLOB 的异同点:

①都可以存储大量超长的数据;

BLOB (Binary Large Object) 以二进制格式保存于数据库中,特别适合保存图片、视

频文件、音频文件、程序文件等;

CLOB (Character Large Object) Character 格式保存于数据库中,适合保存比较长的

文本文件。

九、 SQL SQL SQL 数据类型及其相应的 Java Java Java 数据类型

SQL SQL SQL 数据类型 Java Java Java 数据类型说明

------------------------------------------------------------------------------------------------------------------------------------------

INTEGER 或者 INT int 通常是个 32 位整数

SMALLINT short 通常是个 16 位整数

NUMBER(m, n) java.sql.Numeric 合计位数是 m 的定点十进制数,小数后面有n 位数

DECIMAL(m, n) 同上

DEC(m, n) java.sql.Numeric 合计位数是 m 的定点十进制数,小数后面有 n 位数

FLOAT(n) double 运算精度为 n 位二进制数的浮点数

REAL float 通常是 32 位浮点数

DOUBLE double 通常是 64 位浮点数

CHAR(n) String 长度为 n 的固定长度字符串

CHARACTER(n) 同上

VARCHAR(n) String 最大长度为 n 的可变长度字符串

BOOLEAN boolean 布尔值

DATE java.sql.Date 根据具体设备而实现的日历日期

TIME java.sql.Time 根据具体设备而实现的时间戳

TIMESTAMP java.sql.Timestamp 根据具体设备而实现的当日日期和时间

BLOB java.sql.Blob 二进制大型对象

CLOB java.sql.Clob 字符大型对象

ARRAY java.sql.Array 数组类型www.tarena.com.cn

12

十、面向对象的数据库设计

类的关联,继承在数据库中的体现:

类定义 - - - > 表定义

类属性 - - - > 表字段

类关系 - - - > 表关系

对象 - - - > 表记录

注: Oid( 对象 id) 与业务无关!在数据库中每条记录都对应一个唯一的 id

Id 通常是用来表示记录的唯一性的,通常会使用业务无关的数字类型。

Object id 对象的 id sequence 只有 Oracle 才可用,对象 id OID )使用高低位算法先

生成高位,在生成低位,通过运算获得对象 id

类应当对象到表,属性对应字段,对象对应记录。

㈠类继承关系对应表:

1 、为每一个类建一张表。通过父类的 Oid 来体现继承关系。

特点:在子类表中引用父类表的主键作为自己的外键。

优点:方便查询、属性没有冗余、支持多态。

缺点:表较多,读写效率低。生成报表比较麻烦。

2 、为每一个具体实体类建一个表

特点:父类的属性被分配到每一个子类表中。

优点:做报表比较容易。

缺点:如果父类发生改变会引起所有的子表随之更改。

并且不支持多态,数据会有冗余。

3 、所有的类在一张表中体现,加一个类型辨别字段

特点:效率高,查询不方便,用于重复字段不多时。

优点:支持多态,生成报表很简单。

缺点:如果如何一个类发生变化,必须改表。字段多,难以维护。

㈡类关联关系对应表

1 、一对一关联,类关系对应成表时有两种做法:

一是共享主键,也就是一方引用另一方的主键既作为外键又作为自身的主键。

二是外键引用,一方引用另一方的主键作为自身的外键,并且自己拥有主键。

2 、一对多关联,也就是多端引用一端的主键当作外键,多端自身拥有主键。

3 、多对多关系,多对多关系是通过中间表来实现的,中间表引用两表的主键当作联合

主键,就可以实现多对多关联。www.tarena.com.cn

13

十一、 JDB JDB JDB C C C 应用的分层

分层就是对功能的隔离,并面向接口编程,降低层与层间的耦合性。

软件的分层初步:

JSP Struts

重新封装可复用封装信息懂业务逻辑数据访问层数据层

调业务无技术难度与业务无关

谁依赖谁就看谁调用谁。

软件的分层设计,便于任务的划分、降低层间的耦合。

结合 PMS 的设计方法,思考这样分层的好处。

并且,使代码尽量减少重复,可复用性好,扩展余地加大,而且尽量减少硬编码。

需求:实现对 Person Person Person 类的数据库持久化基本操作( CRUD CRUD CRUD )。

包结构:

B/S 架构和 C/S 架构:

C/S 架构:两层体系结构,主要应用于局域网中。

B/S 架构:三层体系结构,表现层 + 业务逻辑层 + 数据存储层

注:层面越多,软件越复杂,但更灵活。分层是必须的,但凡事均要有个度。

层次一旦确定,数据就必须按层访问,不能跨层访问。层与层之间最好是单向依赖(单

View Controller Action Service

/ Biz

DAO DBDBDB

tarena

pms

service

dao

entity

util

impl

PersonDao.java

PersonDaoOraImpl.java

PersonDaoMysqlImpl.java

AbstractPersonDao.java

PersonService.java

Person.java

JdbcUtil .java DaoFactory.java

ConnectionFactory.java

dao.properties

dbconfig.properties

Model Model Model 部分

对时间的操作:

ps.setDate(1, Date.valueOf( 2007- 12 -13 )); // 注意是用 java.sql.Date

ps.setTimestamp(2, new Timestamp(System.currentTimeMillis()));// 对系统时间的截取www.tarena.com.cn

14

向调用)。

(一) JNDI (命名路径服务)

定义:是 Java 的命名和路径服务接口。而 JDBC Java 的数据库访问接口。 JNDI

JDBC 是平级关系。 JDBC 存储的数据都是以二维表的接口来大规模存储数据;而 JND I

也用于存储数据,存储的是差异性比较大的 Java 对象,是一些比较零散的信息。

JDBC 取数据时用 SQL 语句访问数据。 JDBCAPI 依赖于驱动程序;而 JNDI 依赖于

服务提供者。 JDBC 一般把数据存储到关系型数据库;而 JNDI 一般把数据存储到小型数

据库、文件,甚至是注册表中。

JNDI 的方法是在 javax.naming 包下)

bind(String name, Object obj) 将名称绑定到对象资源,建立指定的字符串和对象资源的

关联;

lookup(String name) 通过指定的字符串获得先前绑定的资源

以下是将资源和 JNDI 命名绑定的方法

public static void bind(String context,Object obj) throws NamingException

{

Properties pro = new Properties();

//Weblogic JNDI 服务器参数

pro.put(InitialContext.INITIAL_CONTEXT_FACTORY,

"weblogic.jndi.WLInitialContextFactory");

pro.put(InitialContext.PROVIDER_URL,"t3://localhost:7001");

Context ctx = new InitialContext(pro);

ctx.bind(context, obj); // 建立指定的字符串和对象资源的关联

}

(二) DataSourse

定义: 1 DataSourse (数据源),包含了连接数据库所需的信息,可以通过数据源获得数

据库连接,有时由于某些连接数据库的信息会变更,所以经常使用包含数据库连接信息的数

据源。

2 、一个标准的数据库连接工厂,保存与数据库相关的信息,可以将数据库的连接信息放在

一个共享的空间进行提取,不用在本地安装。支持 JNDI 的绑定,支持连接池,支持分布

式服务,用 getConnection 方法可获得与数据库的连接。数据源应该由管理员创建(目的www.tarena.com.cn

15

是为了保证数据库的安全)。所以数据源对象一般放在 JNDI 服务器中。

通过 JNDI 获得绑定的资源

public static Object lookup(String context)throws NamingException

{

Properties pro = new Properties();

//Weblogic JNDI 服务器参数

pro.put(InitialContext.INITIAL_CONTEXT_FACTORY,

"weblogic.jndi.WLInitialContextFactory");

pro.put(InitialContext.PROVIDER_URL, "t3://localhost:7001");

Context ctx = new InitialContext(pro);

return ctx.lookup(context); // 通过指定的字符串获得先前绑定的资源。

}

(四)分布式的事务管理器 JTA JTAJTA

分布式事务是通过多个异地数据库执行一组相关操作,要保证原子操作的不可分,也不

用再由自己写 commit rollback ,全部都交给中间服务器( TM )来处理。(两阶段提交),

也就是在中间服务器发送 sql 语句等待数据库回应,都回应操作成功才提交,否则同时回滚。

Regester

TM  execute()

Commit  TM

TM  commit  DB

(五) RowSet RowSet RowSet

行集,这是一个 JavaBean (事件机制),它增强了 ResultSet 的功能,包装了

Connection Statement ResultSet DriverManager 。通过 RowSet 可以获得数据源,

设置隔离级别,也可以发送查询语句,也实现了离线的操作遍历, RowSet 也支持预编译的

Statement

RowSet 中的方法大致上和 ResultSet 相同,当需要使用时请查阅JAVA API 参考文档。

达内科技

commit commit commit

TM TM TM

DB1

DB2

commit commit commit

commit commit commit

con1 con1 con1

con2 con2 con2

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值