JDBC-事务处理(练习)

本文详细介绍了如何在Java中使用JDBC进行事务处理。通过实例演示了事务的开启、提交、回滚以及隔离级别的应用,帮助开发者理解事务在数据库操作中的重要性和使用技巧。
摘要由CSDN通过智能技术生成
package PreparedStatementCURD;
import Instrument.GetConnection;
import Instrument.Operation;
import java.io.IOException;
import java.sql.Connection;
import java.sql.SQLException;


/**
 * @description 事务的问题引入
 * @author Vodka
 * @date 2021/07//18:15
 */
/*
*   1.事务: 一组逻辑操作单元,使数据从一种状态变换到另一种状态 (一组逻辑操作单元代表一组系列相关的DML操作)
*   2.事务处理(事务操作): -保证所有事务都作为一个工作单元来执行,即使出现了故障,都不能改变这种执行方式。
*                            -当一个事务执行多个操作时,要么所有事务执行被commit保存,要么rollback到最初状态.
*   3.数据提交之后,就不能回滚,以下操作会导致数据自动提交:
*               -DDL操作一旦执行,都会自动提交。  (即Delete操作,即使设置set autocommit = false的方式,也是默认提交)
*               -DML默认情况下,一旦执行,也会自动提交。(这个可以通过set autocommit = false 取消DML操作的自动提交)
*               -默认在关闭连接时,会自动提交数据
* 
* */
/*
*   1.原子性(Atomicity):原子性是指事务是一个不可分割的工作单位,事务中的操作要么都发生,要么都不发生。
*   2.一致性(Consistency): 事务必须使数据库从一个一致性状态变换到另外一个一致性状态。
*   3.隔离性(Isolation): 事务的隔离指一个事务的执行不能被其他事务干扰,各个事务独立运行。
*   4.持久性(Durability): 事务一旦被提交,它对数据库中的数据的改变也是永久性的,接下来的其他操作和数据库故障都不会
*                         对它造成影响。
*
*   数据库的并发问题: 当同时运行多个事务时,如果不采取必要的隔离机制,就会导致事务之间各种并发问题:
*   1.脏读: 对于两个t1 ,t2 , t1读取了已经被t2更新但并未提交的数据。在这时,t2 回滚,t1读取的内容就是临时且无效的
*   2.不可重复读: 对于两个事务t1 , t2, t1读取一个字段,然后t2更新了该字段,之后,t1再次读取同一字段,值已经不一样
*   3.幻读:   对于两个事务t1,t2, t1从一个表中读取了一个字段,然后t2在该表插入了一些新的行,之后如果t1再次读取,就会
*             出现跟上一次不同的新数据。
*
*   1.隔离级别:
*       -read uncommitted: 各个事务之间的脏读,不可重复读,幻读等问题都会出现。
*
*       -read committed: 避免了脏读,但不可重复读和幻读还会出现。 (与可重复读级别的区别在于,该级别的事务,
*        在读取某个字段一次结束之后,别的事务就可以对之前事务所读的数据进行更改提交,之前的事务第二次读之后,数据不同了,不可重复读)
*
*       -repeatable read: 避免了脏读和不可重复读,但幻读仍然存在。
*        (与读取已提交数据级别的不同之处是,当前级别可以在某个事务持续重复读取某个字段值时,禁止其它事务对该字段进行更改)
*
* -serializable(串行化):  所有并发问题都可以避免,但性能十分低下。
*
*   1.各个数据库的默认级别: 1.Oracle支持两种事务隔离级别,read committed,serializable。Oracle默认级别为repeatable read.
*                          2.Mysql支持4中事务隔离级别,默认隔离级别为: repeatable read.
*
* 1.在Mysql中设置隔离级别:
*       -每启动一个mysql程序,就会有一个单独的数据库连接,每个数据库连接都有一个全局变量 @@tx_isolation,
*        表示当前的事务隔离级别。(JDBC可以通过程序设置当前连接的隔离级别,不管数据库系统的全局隔离级别是什么)
*
* -查看当前的隔离级别:  select @@tx_isolation;
*
* -设置mysql当前连接的隔离级别: set transaction isolation level read committed;
*
* -设置数据库系统的全局隔离级别:  set global transaction isolation level read committed;
*
* -创建mysql数据库用户: create user tom identified by 'abc123';
*
* -授予权限:
*                   #授予通过网络方式登录的tom用户,对所有库所有表的全部权限,密码为abc123
*                   grant all privileges on xxx to tom @'%'   identified by 'abc123';
*
*                   #给tom用户使用本地命令行方式,授予yyy库下的所有表的增删查改的权限
*                   grant select,insert,delete,update on yyy to tom @localhost identified by  'abc123';
* */
public class Transaction {
   
    public static void main(String []args) {
   
        Connection conn = null;
        try {
   
            conn = GetConnection.getConnection();
            conn.setAutoCommit(false);
            // 案例: 体现事务transaction的特性,A给B转账,要封装在一个事务中,原子性
            //使用一个连接贯穿一个事务的DML函数,而不是操作一次关闭一次,执行完一次事务后再关闭连接
            String DrawUp = "Update Account set deposit = deposit + ?  where UId = ? and UName = ?";
            String WithDraw = "Update Account set deposit = deposit - ?  where UId = ? and UName = ?";
            Operation.UpdateTwo(conn, WithDraw, 1000, 1901, "Vodka");
//            模拟网络异常,检验事务的完整性
//             System.out.println(100 / 0);
            Operation.UpdateTwo(conn, DrawUp, 1000, 1902, "Alice");

            //若事务执行过程没有出错,就手动提交数据
            conn.commit();
        } catch (Exception e) {
   
            e.printStackTrace();
            try{
   
//                如果事务执行过程出错,就进行回滚操作
                conn.rollback();
            }catch (Exception e2){
   
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值