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

时间:2022-12-20 17:57:46


JDBC事务并发产生的问题和事务隔离级别
原子操作使用事务,一组相关的操作。
数据库是事务性的资源,在数据库中所有的操作都与事务相关。JDBC中自动提交是打开的,所以我们感觉不到事务。
 1,如果con.setAutoCommit(false);就可以由我们提交。
 2, update
  insert
  delete
 
 3,    con.commit();或com.rollback();

1,脏读(dirty read),读取到了没有提交的数据。
2,不可重复读(UnPrpeatable Read),两次读取到了不同的数据,就是要保持在同一时间点上两次读取到的数据相同,不能够使查询数据时进行改变。
3,幻读(phantom),在两次查询同一时间点数据时,数据数量发生改变,要保持在同一时间点上两次读取到的数据相同。

事务隔离级别

TRANSACTION_NONE不使用事务。理论上的,实际没用。
TRANSACTION_READ_UNCOMMITTED 可以读取为提交数据。能脏读,这个级别没用,都不控制。
TRANSACTION_READ_COMMITTED 可以避免脏读,不能够读取没提交的数据,最常用的隔离级别  大部分数据库的默认隔离级别
TRANSACTION_REPEATABLE_READ可以避免脏读,不可重复读取,
TRANSACTION_SERIALIZABLE可以避免脏读,重复读取和幻读,(事务串行化)会降低数据库效率

以上的五个事务隔离级别都是在Connection类中定义的静态常量,使用setTransactionIsolation(int level) 方法可以设置事务隔离级别。

JDBC2.0新特性

可滚动结果集(可双向滚动),这种结果集不但可以双向滚动,相对定位,绝对定位,并且可以修改数据信息。

滚动特性
next(),此方法是使游标向下一条记录移动。
previous() ,此方法可以使游标上一条记录移动,前提前面还有记录。
absolute(int row),可以使用此方法跳到指定的记录位置。定位成功返回true,不成功返回false,返回值为false,则游标不会移动。
afterLast() ,游标跳到最后一条记录之后。
beforeFirst() ,游标跳到第一条记录之前。(跳到游标初始位)
first(),游标指向第一条记录。
last(),有彪指向最后一条记录。
relative(int rows) ,相对定位方法,参数值可正可负,参数为正,游标从当前位置向下移动指定值,参数为负,游标从当前位置向上移动指定值。

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

TYPE_SCROLL_INSENSITIVE ,该常量指示可滚动但通常不受其他的更改影响的 ResultSet 对象的类型。
TYPE_SCROLL_SENSITIVE ,该常量指示可滚动并且通常受其他的更改影响的 ResultSet 对象的类型。
         
要使用可滚动结果集时,要在Statement创建时指定参数,才可以使用
Statement st=null;
st=con.createStatement(ReusltSet.TYPE_SCROLL_INSENSITIVE,ResuleSet.CONCUR_UPDATABLE)

ResultSet结果集中,先使用moveToInsertRow(),将游标移到和结果集结构类似的传冲去中
然后可以使用updateXxx(int column,columnType value)方法来更新指定列数据,再使用insertRow() 方法插入记录,
最后将游标指回原位,moveToCurrentRow() 。

能否使用可更新结果集,要看使用的数据库驱动是否支持,还有只能用于单表且表中有主键字段(可能会是联合主键)
,不能够有表连接,会取所有非空字段且没有默认值。

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

批处理更新
Statement
addBatch(String sql), 方法会在批处理缓存中加入一条sql语句
executeBatch() ,执行批处理缓存中的所有sql语句。

PreparedStatement

addBatch() 将一组参数添加到此 PreparedStatement 对象的批处理命令中。
executeBatch() 将一批命令提交给数据库来执行,如果全部命令执行成功,则返回更新计数组成的数组。
PreparedStatement中使用批量更新时,要先设置好参数后使用addBatch()方法加入缓存。
注意:批量更新中只能使用更新或插入语句

execute(String sql),这个方法的返回值是boolean类型,如果返回true就表示sql是一个select语句,可以通过getResultSet()获得结果集,如果是false,sql就是DML语句或者是DDL语句。