事务

简介: 事务概念事务是指一组最小逻辑操作单元,里面有多个操作组成。 组成事务的每一部分必须要同时提交成功,如果一个操作失败,整个操作就回滚。事务ACID特性原子性(Atomicity)原子性是指事务是一个不可分割的工作单位,事务中的操作要么都发生,要么都不发生。

事务概念

事务是指一组最小逻辑操作单元,里面有多个操作组成。 组成事务的每一部分必须要同时提交成功,如果一个操作失败,整个操作就回滚。
事务ACID特性

  • 原子性(Atomicity)

原子性是指事务是一个不可分割的工作单位,事务中的操作要么都发生,要么都不发生。

  • 一致性(Consistency)

事务必须使数据库从一个一致性状态变换到另外一个一致性状态。

  • 隔离性(Isolation)

事务的隔离性是多个用户并发访问数据库时,数据库为每一个用户开启的事务,不能被其他事务的操作数据所干扰,多个并发事务之间要相互隔离。

  • 持久性(Durability)

持久性是指一个事务一旦被提交,它对数据库中数据的改变就是永久性的,接下来即使数据库发生故障也不应该对其有任何影响

核心api

|-- Connection
void setAutoCommit(boolean autoCommit) ;  设置事务是否自动提交
                                      如果设置为false,表示手动提交事务。
void commit() ();       手动提交事务
void rollback() ;       回滚(出现异常时候,所有已经执行成功的代码需要回退到事务开始前的状态。)

案例(张三给李四转账)

  • 代码
package cn.persistXl.app;

import cn.persistXl.util.JdbcUtil;
import org.junit.Test;

import java.sql.*;

/**
 * @author persistXL
 * @data 2018/4/30 20:25
 */
public class AccountDao {
    //全局参数
    Connection conn = null;
    PreparedStatement pstmt = null;
    ResultSet rs = null;

    //转账,没有使用事物

    public void trans() {

        //准备sql
        String sql_zs = "";
        String sql_ls = "";

        try {

            //获取连接
            conn = JdbcUtil.getConnection();
            //使用默认开启的隐士事物

            /**
             * 第一次执行sql
             */
            //预编译sql
            pstmt = conn.prepareStatement(sql_zs);
            //设置参数
            //执行sql
            pstmt.executeUpdate();

            /**
             * 第二次执行sql
             */
            //预编译sql
            pstmt = conn.prepareStatement(sql_ls);
            //设置参数
            //执行sql
            pstmt.executeUpdate();

        } catch (Exception e) {
            e.printStackTrace();
        }finally {
            JdbcUtil.close(conn,pstmt,null);
        }
    }
    //使用事物
    public void trans1(){
        //准备sql
        String sql_zs = "";
        String sql_ls = "";

        try {

            //获取连接
            conn = JdbcUtil.getConnection();

            //设置事物为手动提交

            conn.setAutoCommit(false);

            /**
             * 第一次执行sql
             */
            //预编译sql
            pstmt = conn.prepareStatement(sql_zs);
            //设置参数
            //执行sql
            pstmt.executeUpdate();

            /**
             * 第二次执行sql
             */
            //预编译sql
            pstmt = conn.prepareStatement(sql_ls);
            //设置参数
            //执行sql
            pstmt.executeUpdate();

        } catch (Exception e) {
            try {
                // 出现异常需要回滚事物
                conn.rollback();
            } catch (SQLException e1) {
                e1.printStackTrace();
            }
            e.printStackTrace();
        }finally {
            try {
                //所有操作执行成功,提交事物
                conn.commit();
                JdbcUtil.close(conn,pstmt,null);
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
    }

    //使用事物,回滚到指定的代码段
    
    public void trans2() {

        Savepoint sp = null;
        //准备sql
        String sql_zs1 = "";
        String sql_ls1 = "";
        String sql_zs2 = "";
        String sql_ls2 = "";

        try {

            //获取连接
            conn = JdbcUtil.getConnection();
            conn.setAutoCommit(false);

/*** 第一次转账 */


            /**
             * 第一次执行sql
             */
            //预编译sql

            pstmt = conn.prepareStatement(sql_zs1);
            //执行sql

            pstmt.executeUpdate();

            /**
             * 第二次执行sql
             */
            //预编译sql

            pstmt = conn.prepareStatement(sql_ls1);
            //执行sql

            pstmt.executeUpdate();

            //回滚到这个位置
            sp = conn.setSavepoint("trans");

/*** 第二次转账 */

            pstmt = conn.prepareStatement(sql_zs2);
            pstmt.executeUpdate();
            pstmt = conn.prepareStatement(sql_ls2);
            pstmt.executeUpdate();

        } catch (Exception e) {
            try {
                //回滚到指定位置
                conn.rollback(sp);
            } catch (SQLException e1) {
                e1.printStackTrace();
            }
            e.printStackTrace();
        }finally {
            JdbcUtil.close(conn,pstmt,null);
        }
    }
}

相关文章
|
8月前
|
弹性计算 运维 安全
阿里云云服务诊断工具评测报告
阿里云云服务诊断工具评测报告
179 13
|
8月前
|
存储 缓存 Serverless
使用云存储构建云上推理平台
本文介绍了大模型分布式推理的工作流、IO分析、存储需求及解决方案。通过分布式缓存和P2P能力,优化了大规模并发场景下的模型加载与分发效率,提升了推理性能。NAS文件存储和OSS加速器在高并发读取和小模型缓存中表现出色,支持秒级加载和高效数据处理。阿里云存储为开发者提供了稳定、高效的推理环境,助力AI应用快速落地。
|
10月前
|
网络协议 安全 算法
OSPFv3新特性介绍
OSPFv3新特性介绍
197 4
|
10月前
|
机器学习/深度学习 存储 算法
基于Actor-Critic(A2C)强化学习的四旋翼无人机飞行控制系统matlab仿真
基于Actor-Critic强化学习的四旋翼无人机飞行控制系统,通过构建策略网络和价值网络学习最优控制策略。MATLAB 2022a仿真结果显示,该方法在复杂环境中表现出色。核心代码包括加载训练好的模型、设置仿真参数、运行仿真并绘制结果图表。仿真操作步骤可参考配套视频。
351 0
|
SQL 分布式计算 资源调度
常用大数据组件的Web端口号总结
这是关于常用大数据组件Web端口号的总结。通过虚拟机名+端口号可访问各组件服务:Hadoop HDFS的9870,YARN的ResourceManager的8088和JobHistoryServer的19888,Zeppelin的8000,HBase的10610,Hive的10002。ZooKeeper的端口包括客户端连接的2181,服务器间通信的2888以及选举通信的3888。
495 2
常用大数据组件的Web端口号总结
什么是CAP理论?
CAP理论是分布式系统设计中的一个基本原则,它指出在一个分布式系统中,一致性(Consistency)、可用性(Availability)和分区容错性(Partition Tolerance)这三个目标无法同时满足,最多只能同时满足其中的两个。
310 0
|
前端开发 Java 数据库连接
软件开发者的时间都去哪儿了?后端开发核心技能——抽象建模
服务端开发工程师在大部分工作时间里并不是在写代码,而是在抽象建模。工程师需将业务需求抽象成领域模型、模块、服务和系统,面向对象开发时需抽象出类和对象,面向过程开发时抽象出方法和函数。某种意义上,软件的本质就是抽象,建模则是系统地实施抽象的过程。作为一种将事物形象化的有效手段,建模可将现实世界中的事物及事物之间的关系准确地表达出来。本文通过一个实际案例,详细解读业务抽象建模的好处。
233 1
软件开发者的时间都去哪儿了?后端开发核心技能——抽象建模
|
运维 Java 开发者
深入浅出:使用Docker容器化改善Java应用的部署与运维
在快速迭代与持续集成的开发周期中,如何确保Java应用的一致性、高效部署及易于管理成为了开发与运维团队面临的重大挑战。本文将探讨Docker容器技术如何为Java应用提供一种轻量级、可移植的解决方案,实现环境一致性、简化配置过程并提高开发到生产的流程效率。我们将从Docker的基本概念入手,通过实例详细说明如何将传统的Java应用容器化,以及如何利用Docker Compose来管理多容器应用,最后探讨在使用Docker部署Java应用时的最佳实践和常见问题解决策略。
578 1