浅谈jdbc

一:JDBC的链接过程
1、加载类库(驱动jar包)到JVM

mysql-connector-java 5:com.mysql.jdbc.Driver
mysql-connector-java 6以上 :com.mysql.cj.jdbc.Driver
Class.forName("com.mysql.cj.jdbc.Driver");

2、加载驱动建立连接
(1)useUnicode=true&characterEncoding=UTF-8作用

存数据时:数据库在存放项目数据的时候会先用UTF-8格式将数据解码成字节码,然后再将解码后的字节码重新使用GBK编码存放到数据库中。

取数据时:在从数据库中取数据的时候,数据库会先将数据库中的数据按GBK格式解码成字节码,然后再将解码后的字节码重新按UTF-8格式编码数据,最后再将数据返回给客户端。
(2)useSSL表明是否使用SSL连接
useSSL=true:是
useSSL=false:否
3、创建Statement

Statement state = conn.createStatement();

4、通过Statement执行SQL语句
5、若执行的是DQL语句,则会得到查询结果集Result,遍历该结果集得到查询内容。

6、关闭连接

conn.close();

二、JDBC的事务
(一)概念
一个事务是由一条或者多条对数据库操作的SQL语句所组成的一个不可分割的单元,只有当事务中的所有操作都正常执行完了,整个事务才会被提交给数据库;如果有部分事务处理失败,那么事务就要回退到最初的状态,因此,事务要么全部执行成功,要么全部失败。

事务也可以设置保存点SavePoint,当事务执行发生错误的时候,可以选择回滚到保存点。在JDBC编程中,事务默认是自动提交的,事务是通过commit提交或者rollback来回滚的。

void setAutoCommit(boolean autoCommit)throws SQLException;

可以通过JDBC Connection连接对象的setAutoCommit方法来设置事务是否自动提交。
(二)事物的 ACID特性
每一个事务必须满足下面的4个特性:
事务的原子性(Atomic):
事务是一个不可分割的整体,事务必须具有原子特性,即当数据修改时,要么全执行,要么全不执行,即不允许事务部分的完成。

事务的一致性(Consistency):
一个事务执行之前和执行之后,数据库数据必须保持一致性状态。数据库的一致性状态必须由用户来负责,由并发控制机制实现。就拿网上购物来说,你只有让商品出库,又让商品进入顾客的购物车才能构成一个完整的事务!由于并发操作带来的数据不一致性包括读脏数据(脏读),不可重复读和虚读(幻读)。

事务的隔离性(Isolation):
当两个或者多个事务并发执行时,为了保证数据的安全性,将一个事物内部的操作与其它事务的操作隔离起来,不被其它正在执行的事务所看到,例如对任何一对事务T1和T2,对T1而言,T2要么在T1开始之前已经结束,要么在T1完成之后再开始执行。**隔离性使得每个事务的更新在它被提交之前,对其它事务都是不可见的。**让我们看看事务处理之父Jim Gray对事务隔离性的定义[1]:Isolation: Concurrently executing transactions see the stored information as if they were running serially (one after another).

事务的持久性(Durability):
事务完成以后,DBMS保证它对数据库中的数据的修改是永久性的,即使数据库因为故障出错,也应该能够恢复数据!
(三)事务的隔离级别
事务处理不经隔离,并发执行事务时通常会发生以下的问题:
脏读(Dirty Read):一个事务读取了另一个事务未提交的数据。例如当事务A和事务B并发执行时,当事务A更新后,事务B查询读取到A尚未提交的数据,此时事务A回滚,则事务B读到的数据就是无效的脏数据。(事务B读取了事务A尚未提交的数据)
不可重复读(NonRepeatable Read):一个事务的操作导致另一个事务前后两次读取到不同的数据。例如当事务A和事务B并发执行时,当事务B查询读取数据后,事务A更新操作更改事务B查询到的数据,此时事务B再次去读该数据,发现前后两次读的数据不一样。(事务B读取了事务A已提交的数据)
虚读(Phantom Read)/幻读:一个事务的操作导致另一个事务前后两次查询的结果数据量不同。例如当事务A和事务B并发执行时,当事务B查询读取数据后,事务A新增或者删除了一条满足事务B查询条件的记录,此时事务B再去查询,发现查询到前一次不存在的记录,或者前一次查询的一些记录不见了。(事务B读取了事务A新增加的数据或者读不到事务A删除的数据)

由于多个线程会请求相同的数据,事务之间通常都会用锁互相隔离,由于数据库支持不同类型的锁,因此Java JDBC支持不同级别的事务处理,它们由Connection对象指定。

在JDBC中,定义了以下5种事务隔离级别:

  1. TRANSACTION_NONE。 表示不支持事务。
  2. TRANSACTION_READ_UNCOMMITTED。未提交读。说明在提交前一个事务可以看到另一个事务的变化。这样读”脏”数据,不可重复读和虚读都是被允许的。
  3. TRANSACTION_READ_COMMITTED。已提交读。说明读取未提交的数据是不允许的。这个级别仍然允许不可重复读和虚读产生。
  4. TRANSACTION_REPEATABLE_READ。可重复读。说明事务保证能够再次读取相同的数据而不会失败,但虚读仍然会出现。
  5. TRANSACTION_SERIALIZABLE。可序列化/串行化。是最高的事务级别,它防止读脏数据,不可重复读和虚读。

注意:事务隔离级别越高,为避免冲突所花费的性能也就越多。可以通过Connection接口下面的函数来设置事务的隔离级别:

void setTransactionIsolation(int level)throws SQLException;

(四)JDBC如何处理事务
在JDBC当中,可以通过调用setAutoCommit(false)方法来禁止自动提交事务,然后就可以把多个数据库操作的SQL表达式作为一个事务,在操作完成以后调用commit方法来实现事务提交,如果其中一个表达式失败,就会抛出异常而不会调用commit。在这种情况下,就可以在异常代码处理中调用rollback对已经发生的事务操作进行回滚。通过此种方法可以保持对数据库进行多次操作后,数据仍然是保持一致的。如果是使用JDBC对数据库的事务设置隔离级别的话,也应该是在调用Connection对象的setAutoCommit(false)方法之前,调用Connection对象的setTransactionIsolation(level)即可设置当前链接的隔离级别,至于参数level,可以使用Connection对象的字段:
在这里插入图片描述
在JDBC中设置隔离级别的部分代码:

Connection conn = null;
Statement st = null;
ResultSet rs = null;
try{	
	conn = jdbcUtils.getConnection();
	//设置该链接的隔离级别
	conn.setTransactionIsolation(Connection.TRANSACTION_SERIALIZABLE);
	conn.setAutoCommit(false);//开启事务
}

隔离级别的设置只对当前链接有效。对于使用MySQL命令窗口而言,一个窗口就相当于一个链接,也称作一个会话,当前窗口设置的隔离级别只对当前窗口中的事务有效;对于JDBC操作数据库来说,一个Connection对象相当于一个链接(或者称一个会话),而对于Connection对象设置的隔离级别只对该Connection对象有效,与其他链接Connection对象无关,也就是说每个Connection对象都需要设置各自的隔离级别。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值