Java Web学习之 JDBC 进阶(事务处理,连接池)

学习Java Web 基础篇,可以熟练的完成对数据库的增删改查等基本操作,该篇讲解JDBC 的高级用法,包括事务处理,连接池,这些技术构成了JAVA Web 分层开发中持久层的核心要件,是Java 程序操作数据库的重要支撑。

数据库的事务:

1.事务的概念:

    事务,是指数据库中的一个操作序列,它由一条或多条SQL 命令所组成,这些SQL 命令不可分割,只有当事务中所有的SQL 命令被成功执行后,整个事务引发的操作才能被更新到数据库。

    如下面两条Sql语句(李磊购物需要向商家支付500的事务):

     Update account Set money=money-500 Where name= "lilei";

     Update account Set money=money+500 where name="shop";

  这两条 Sql 命令属于同一个操作序列,只有全部成功执行时,整个事务才会被更新到数据库,否则,全部SQL命令都要被取消,这就避免了李磊账户上面少了500元而商家账户金额不变的情况。

Mysql 数据库共有两种方式来管理事务:

   1.自动提交事务

    默认状态下,MySQL 自动提交事务,即每执行一条SQL 语句就提交一次事务,可以通过Mysql 全局变量 autocommit 进行查看,SQl 语句如下:

    Show  Variables like  '%commit%';

   通过Sql 语句查看当前数据库的事务状态,执行结果如下:

  从以上的执行结果可以看出,autocommit 的值为 On,这时,数据库事务是默认提交的。

 关闭数据库自动提交事务的功能,SQL 语句如下:

    Set AutoCommit=0; # 0 是 OFF,1是 ON

  当 autocommit 显示为OFF 状态是需要手动提交,手动提交事务,首先要开启事务(Start  Transaction),再提交( Commit)或回滚(Rollback) 事务。提交事务回将整个事务中的操作更新到数据库,回滚事务则会取消整个事务中已执行的所有操作,当手动提交事务时,上文实例中购物支付触发的Sql 语句如下:

   START TRANSACTION   # 开启事务

   Update account SET money =money-500  where name ="lilei";

   Update account SET money =money+500 where name='shop'

  COMMIT;  # 提交事务

  # 或者 (提交或回滚二选一)

  ROLLBACK  #回滚事务

2.事务的ACID 属性

    ACID,是数据库事务正确执行的四个基本要素的缩写,它包含原子性(Atomicity)一致性(Consistency),隔离性(Isolation),持久性(Durability),一个支持事务的数据库,必须要具备这四种特性,否则在事务管理中无法保证数据的正确性。

   原子性:整个事务中所有的操作都是不可分割的,要么完全执行,要么完全不执行,不能停留在中间某个环节,事务的操作序列如果全部成功,就必须完全应用到数据库,如果有一项操作失败,就不能对数据库有任何影响。

   一致性:事务完成时,数据必须是一致的,即与事务开始之前,数据存储中的数据处于一致状态,保证数据的无损,如转账为例,两个账户中的总数不能变。

   隔离性:隔离性是指事务之间相互独立,彼此隔离,当多个用户访问数据库时,如操作同一张表,数据库为每一个用户开启的事务,不能被其他事务所干扰。

   持久性:持久性是指事务一旦提交,那么对数据库中的数据的改变就是永久性的,即使数据库系统遇到故障也不会丢失事务的处理效果。

3.数据库的隔离级别:

   对数据库而言,最明显的特征是资源可以被多个用户共享,当相同的数据库资源被多个用户(多个事务)同时访问时,如果没有采取必要的隔离措施,就会导致各种并发问题,破坏数据的完整性。

如果不考虑隔离性,数据库将会存在如下三种并发问题:

 1.脏读

   一个事务读到了另一个事务尚未提交的更改数据

2.不可重复读

  不可重复读是指一个事务读取数据后,另一个事务执行更新操作,使第一个事务无法再现前一次的读取结果。

3.幻读

  幻读是指一个事务读取数据后,另一个事务执行插入操作,使第一个事务无法再现前一次的读取结果,例如,事务T1 两次统计所有账户的总金额,在这期间,事务T2  插入了一条新记录,是的两次统计的金额不一致。

  为了解决并发造成的问题,数据库规范定义了4种隔离级别,用于限定事务之间的可见性,不同的事务隔离级别对应的解决数据并发问题的能力是不同的:

                               

         read uncommitted: 一个事务读取到另一个事务没有提交的数据

         read committed:一个事务读到另一个事务提交后的数据

        repeatable read(可重复读): 在一个事务中读到的数据始终一致,无论其他事务是否提交

        serializable:只能同时执行一个事务,相当于事务中的单线程

以上4中隔离级别中,安全性最高的是Serializable (串行化),最低点是 read uncommitted (读未提交),当然,安全性能越高,执行效率就越低,serilizable这样的级别,就是以锁表的形式,使其他事务只能锁在外边等待,所以平时选用何种隔离级别应该根据实际情况来定。Mysql数据库默认的隔离级别为repetable read。

4.JDBC 实现事务处理:

      在JDBC 的数据库操作中,Connection 对象为事务管理提供了如下3个方法:

    setAutoCommit(boolean autocommit):设置是否自动提交事务

    commit() :提交事务

    rollback():回滚

  默认情况下,JDBC 的事务是自动提交的,一条数据库的更新表达式代表一项事务,操作成功后,系统将自动调用commit()来提交,否则将调用rollback()来回滚

public class TestPayMent {

    public static void main(String[] args) throws ClassNotFoundException, SQLException {

        Class.forName("com.mysql.jdbc.Driver");
        Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/chapter02", "root", "123456");

        //关闭事务的自动提交
        conn.setAutoCommit(false);
        //lilei 的账户减去100元
        PreparedStatement  pst= conn.prepareStatement("UPDATE account SET money=money-100 where aname=?");
        pst.setString(1,"lilei");

        pst.executeUpdate();

        PreparedStatement pst2= conn.prepareStatement("UPDATE  account SET money=money+100 where aname=?");
        pst2.setString(1,"shop");
        pst2.executeUpdate();

        //提交事务
        conn.commit();
    }
}

代码执行完毕后,再次发送select 语句,JDBC 已将本次事务引发的操作提交到数据库中:

 

数据库的连接池:

 1.

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

焱宣

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值