JDBC编程(三)

  • 一、事务-掌握

JDBC当你执行增删改语句时,事务会自动开启。每插入一条语句,开启一个事务,不能达到数据一致

JDBC中如何手工控制事务?

什么时候使用自动事务?什么时候使用手工事务?

  1. 当你一次只操作一张表时,且没有批处理时则可以使用自动事务;
  2. 如果往同一张表插入多条记录,这多条记录有特别要求说要么同时成功,要么同时失败时就要使用手工事务;如果在同一个方法内部使用JDBC语句操作了多张表,必须使用手工事务(这样才能达到统一控制的目的)
conn.setAutoCommit(false);//JDBC设置不自动提交事务,此时事务打开了,可手工控制事务

事务(ACID)

  1. 原子性(atomicity):组成事务处理的语句形成了一个逻辑单元,不能只执行其中的一部分。 
  2. 一致性(consistency):在事务处理执行前后,数据库是一致的(数据库数据完整性约束)。 
  3. 隔离性(isolcation):一个事务处理对另一个事务处理的影响。 
  4. 持续性(durability):事务处理的效果能够被永久保存下来 。
  5. 在JDBC中,事务默认是自动提交的
  6. 通过Connection的setAutoCommit()方法来设置事务的提交属性。如:connection.setAutoCommit(false);//打开事务。
  7. 通过Connection的getAutoCommit()方法来获得当前事务的提交方式
  8. 通过Connection的commit()方法来提交事务
  9. 通过Connection的rollback()方法来回滚事务

事务(SavePoint-创建保存点)-了解

当只想撤销事务中的部分操作时可使用SavePoint

     //创建保存点
    SavePoint sp = connection.setSavepoint();
    connection.rollerbak(sp);
    connection.commit();

注:Oracle数据库的classes12.jar驱动程序对保存点的支持存在缺陷,所以无法使用,如果要在Oracle中使用保存点功能,需要使用odjbc1.4.jar,MySQL的数据库驱动对保存点的支持较为完善,可以使用。

事务(JTA)

JDBC是不能够进行跨数据库事务管理的

跨越多个数据源的事务,使用JTA容器(应用服务器)实现事务。

分成两阶段提交。

javax.transaction.UserTransaction tx = (UserTransaction)ctx.lookup(“jndiName");
tx.begin();
//connection1 connection2 (可能来自不同的数据库)… 
tx.commit();
//tx.rollback();

隔离级别多线程并发读取数据时的正确性

connection.setTransactionIsolation(Connection.TRANSACTION_READ_COMMITTED); 

√ :可能出现,X:不会出现

隔离级别 

脏读 

不可重复读 

幻读 

读未提交(Read uncommitted)

读已提交(Read committed)

x

可重复读(Repeatable read)

x

x

可串行化(Serializable )

x

x

x

一般不会通过Java应用程序去修改数据库的隔离级别,一般都是使用数据库默认的隔离级别(读已提交),如果将数据库的隔离级别设置过高,会导致数据库并发性能的下降。

  • 脏读(dirty reads) 

          一个事务读取了另一个未提交的并行事务写的数据。 

  • 不可重复读(non-repeatable reads) 

          一个事务重新读取前面读取过的数据, 发现该数据已经被另一个已提交的事务修改过。 

  • 幻读(phantom read) 

       一个事务重新执行一个查询,返回一套符合查询条件的记录, 发现这些记录因为其他最近提交的事务而发生了改变。

使用CallableStatement调用存储过程

当不直接使用SQL语句,而是调用数据库中的Store Procedure(存储过程)时,要用到Callable Statement

CallabelStatement从PreparedStatement继承

CallableStatement(从PreperedStatement扩展来)
cs=connection.prepareCall(“{call  psname(?,?,?)}”);
cs.registerOutParameter(index,Types.INTEGER);
cs.setXXX(i, xxxx);
cs.executeUpdate();
int id=cs.getInt(index);

其他的几个API

PreparedStatement.getGeneratedKeys()
PreparedStatement ps = connection.prepareStatement(sql,Statement.RETURN_GENERATED_KEYS);
ps.executeUpdate();
ResultSet rs = ps.getGeneratedKeys();
rs.getInt(1);

 批处理,可以大幅度提升大量增、删、改的速度。

PreparedStatement.addBatch();
PreparedStatement.executeBatch();
  • 二、批处理-掌握

可以将一些相关的数据库操作放到同一个Batch中:

  1. 使用Statement的addBatch()方法,将一系列的操作放到同一个Batch中
  2. 利用Statement的executeBatch()方法,来成批执行放到同一个Batch中的操作
  3. 可以将Batch操作和事务结合起来使用。将放到 Batch中的操作当成一个事务
conn.setAutoCommit(false);
Statement stmt = conn.createStatement();
stmt.addBatch(“insert into table1…”);
stmt.addBatch(“insert into table2…”);
stmt.addBatch(“update table3…”);
…
stmt.executeBatch();
conn.commit()
…

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值