iis服务器助手广告广告
返回顶部
首页 > 资讯 > 数据库 >深入详解数据库事务(开发必用)
  • 458
分享到

深入详解数据库事务(开发必用)

JDBCmysql事务详解java 2023-09-11 15:09:12 458人浏览 泡泡鱼
摘要

 一.事务的概念: 一组逻辑操作单元,时数据从一个状态转换到另一个状态。  二.事务处理的原则:         保证所有的事务都被当做一个操作单元来执行,即使出现了故障,也不能改变这种处置原则。要么与事务相关的数据全部被修改,

 一.事务的概念:

一组逻辑操作单元,时数据从一个状态转换到另一个状态。

 二.事务处理的原则:

        保证所有的事务都被当做一个操作单元来执行,即使出现了故障,也不能改变这种处置原则。要么与事务相关的数据全部被修改,并永远的提交保存下来,要么所有的事务全部回滚到事务没被执行的状态。

三.那些操作会影响数据库的提交

(一).数据库连接一旦断开,数据库的数据都被会提交

(二).DDL操作完成,数据自动提交,并且无法回滚

(三).DML操作默认为提交,但是可以通过 set auto commit = false;来设置不允许自动提交

四.模拟事务提交

事务执行过程图:

 

 

通用的包含事务的更新方法

        public static int update(Connection conn,String sql,Object... args){        int temp = -1;        PreparedStatement pst = null;        try{            //2.预编译sql语句            pst = conn.prepareStatement(sql);            //3.填充占位符            for (int i = 0; i < args.length; i++) {                pst.setObject(i+1,args[i]);            }            //4.执行            //            pst.execute();            temp = pst.executeUpdate();        }catch (Exception e){            e.printStackTrace();        }finally {            //5.释放资源            closeResource(null,pst);        }        return temp;    }

(一).模拟存在异常情况下的102给103转账100元操作;

public void testTransaction() throws Exception {        Connection conn = null;        //102向103转账100元        try{            conn = JDBCUtils.getConnection();            //关闭DML自动调教功能            conn.setAutoCommit(false);            String sql1 = "update user_tab set balance = balance - 100 where id = ?";            update(conn,sql1,102);            //模拟异常            System.out.println(10/0);            //103接受102转账100元            String sql2 = "update user_tab set balance = balance + 100 where id = ?";            update(conn,sql2,103);            //提交事务            conn.commit();            System.out.println("转账成功");        }catch (Exception e ){            e.printStackTrace();            //出现异常数据回滚            conn.rollback();        }finally {//将自动提交功能设置还原为true            conn.setAutoCommit(true);            JDBCUtils.closeResource(conn,null);        }    }

转账失败

 (二).模拟不存在异常下转账的情况

public void testTransaction() throws Exception {        Connection conn = null;        //102向103转账100元        try{            conn = JDBCUtils.getConnection();            //关闭DML自动调教功能            conn.setAutoCommit(false);            String sql1 = "update user_tab set balance = balance - 100 where id = ?";            update(conn,sql1,102);            //模拟异常//        System.out.println(10/0);            //103接受102转账100元            String sql2 = "update user_tab set balance = balance + 100 where id = ?";            update(conn,sql2,103);            //提交事务            conn.commit();            System.out.println("转账成功");        }catch (Exception e ){            e.printStackTrace();            //出现异常数据回滚            conn.rollback();        }finally {//将自动提交功能设置还原为true            conn.setAutoCommit(true);            JDBCUtils.closeResource(conn,null);        }    }

转账成功

四.事务的ACID属性

(一).事务的属性

1.原子性:

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

2.一致性:

        事务必须使数据库从一个一致状态转换到另一个一致状态

3.隔离性:

        事务并发在执行时,各个事务之间的数据互不干扰的,各个事务 之间的数据不受任何影响

4.持久性:

        事务一旦被提交,就是永久性的改变,接下来发生的事或数据库故障都不会对其有任何我影响。

(二).事务的并发问题

1.脏读:

        读出了未提交的数据。

        事务T1,事务T2,T1读入一个数据段A,读出值为1,此时T2修改了A的值,T1将A= 2的值读出,但此时T2撤销了事务,回滚到A=1的阶段。此时T1读出的数据无效,即为脏读:

2.不可重复读:

只读提交的数据,并且第一次读出来是什么,在提交之前,读出来的东西和第一次保持一致;

        事务T1在第一次读到A=1,在读到以后,无论其他事务(T2)对字段A怎么更新提交(A=2),T1在提交前读出A字段永远都是A=1;

3.幻读:

事务T1第一次读出100条数据,T2插入3条数据并提交,T1提交后,T1再次读,读出103条数去,即为幻读,

(三).隔离级别

1. READ UNCOMMITED(读未提交的数据)

2. READ COMMITED(读已提交的数据)

3. REPEATED READ(可重复读)

4. 串行化:SERIALIZABLE(各个事务顺序执行)

(四).java代码实现隔离级别(框架必用,提前打基础

package Transaction;import UpAndSelMethod.Method;import jdbcUtil.JDBCUtils;import org.junit.Test;import userBean.User;import java.sql.Connection;//*********卧槽,为啥我设置隔离级别为读未提交却读不出来修改了却为体骄傲的数据,麻了******************public class Test隔离级别 {    //**************************测试事务并发问题与隔离级别的关系*********************************    //测试查询    @Test    public void testTransactionSelect() throws Exception {        Connection conn = JDBCUtils.getConnection();        //设置sql语句        String sql = "select id,name,balance from user_tab where id = ?";        //查看当前连接的的隔离级别        System.out.println(conn.getTransactionIsolation());        //设置当前连接的隔离级别为读未提交        conn.setTransactionIsolation(Connection.TRANSACTION_READ_UNCOMMITTED);        System.out.println(conn.getTransactionIsolation());        User user = Method.selectinfo(User.class, sql, 103);        System.out.println(user);    }    //测试更新    @Test    public void testTransactionUpdate() throws Exception {        //获取连接        Connection conn = JDBCUtils.getConnection();        //设置自动提交为false        conn.setAutoCommit(false);        //sql        String sql = "update user_tab set balance = ? where id = ?";        //执行更新操作        Method.update(conn,sql,5000,103);        //线程睡眠15秒        Thread.sleep(15000);        //睡眠结束        System.out.println("修改完成");    }}

 

来源地址:https://blog.csdn.net/qq_52655865/article/details/123977638

您可能感兴趣的文档:

--结束END--

本文标题: 深入详解数据库事务(开发必用)

本文链接: https://www.lsjlt.com/news/403317.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作