美文网首页
Java篇-事务

Java篇-事务

作者: TianTianBaby223 | 来源:发表于2018-10-18 19:17 被阅读19次

一 : 事务简述

一个事情由N个单元组成,N个组成单元同时成功,要不n个单元就同时失败,就是将N个组成单元放入一个事务中

二 : mysql 中的事务操作

默认的事务 : 一条sql语句就是一个事务,默认就是开启事务并提交事务

手动事务 :

(1). 显示开启的一个事务 : start transaction
(2). 事务提交 : commit 代表从开启事务到事务提交,中间的所有的sql都认为有效真正的更新数据库
(3). 事务的回滚 : rollback代表事务的回滚 从开启事务到事务回滚,中间的所有sql操作都认为无效的,数据库没有被更新

开启事务没有提交,默认就是事务的回滚.
开启事务后,没有进行提交,查询也可以可以,因为此时数据没有提交到磁盘上,只是放在日志上面.

三 : JDBC事务操作

默认是自动事务
开启事务 : conn.setAutoCommit(false)
提交事务 : conn.commit()
回滚事务 : conn.rollback();
注意 : 执行sql的connection与开启事务的connnection必须是同一个才能对事务进行控制

public static void main(String[] args){
        //通过jdbc去控制事务
        //command+shift+t 方式预览需要的包路径
        Connection conn = null;
        try {
            //注册驱动
            Class.forName("com.mysql.jdbc.Driver");
            //获得connection 
             conn = DriverManager.getConnection("jdbc:mysql:///TZproject", "root", "newpass");
            //手动开启事务
            conn.setAutoCommit(false);
            
            //获得执行平台
            Statement stmt = conn.createStatement();
            
            //操作sql-默认事务
            stmt.executeUpdate("insert into user values (null,'jack','333',null)");
            
            //提交事务
            conn.commit();
            stmt.close();
            conn.close();
        } catch (Exception e) {
            try {
                conn.rollback();
            } catch (SQLException e1) {
                // TODO Auto-generated catch block
                e1.printStackTrace();
            }
            e.printStackTrace();
        }
    }

四 : DBUtils事务操作

有参构造:QueryRunner runner = new QueryRunner(DataSource dataSource);
有参构造将数据源(连接池)作为参数传入QueryRunner,QueryRunner会从连​接池中获得一个数据库连接资源操作数据库,所以直接使用无Connection参数​的update方法即可操作数据库
无参构造:QueryRunner runner = new QueryRunner();
无参的构造没有将数据源(连接池)作为参数传入QueryRunner,那么我们在使​用QueryRunner对象操作数据库时要使用有Connection参数的方法

public static void main(String[] args) {
        QueryRunner runner = new QueryRunner();
        Connection conn = null;
        try {
            //获得一个connection
            conn = DataSourceUtils.TZgetConnection();
            //开启事务
            conn.setAutoCommit(false);
            String sql = "update user set password = '000' where username = 'jack'";
            runner.update(conn,sql);
            conn.commit();
        } catch (SQLException e) {
            e.printStackTrace();
            try {
                conn.rollback();
            } catch (SQLException e1) {
                e1.printStackTrace();
            }
        }   
    }

五 : ThreadLocal

java.lang.ThreadLocal该类提供了线程局部(thread-local)变量,用于在当前线程中共享数据,ThreadLoal工具底层就是一个Map,key存放当前线程,value存放共享数据
ThreadLocal操作

  • set(value)
  • get
  • remove

六 : 使用事务完成转账

(1)页面

页面

(2)WEB层

protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

            response.setContentType("text/html;charset=UTF-8");
            
            //接收转账的参数
            String outStr = request.getParameter("out");
            String inStr = request.getParameter("in");
            double money = Double.parseDouble(request.getParameter("money"));
    
            //调用业务层的转账方法
            TransferService service = new TransferService();
            boolean isSucess = service.transfer(outStr,inStr,money);
            if (isSucess) {
                response.getWriter().write("转账成功!");
            }else {
                response.getWriter().write("转账失败...!");

            }
    }

(3)Service层

提交放在finllay 中,假如crash回滚到事务开启处,再提交关闭一下.一个还不错的习惯.

public boolean transfer(String outStr, String inStr, double money) {
        boolean isTransferSuncess = true;
        
        TransferDao dao = new TransferDao();
        //开启事务
        try {
            //开启事务
            DataSourceUtils.startTransaction();
            //转出钱
            dao.out(outStr,money);
            int i = 10/0;
            //转入钱
            dao.in(inStr,money);

        } catch (Exception e) {
            isTransferSuncess = false;
            try {
                //默认回滚点为19行
                DataSourceUtils.rollback();
                
            } catch (SQLException e1) {
                e1.printStackTrace();
            }
            e.printStackTrace();
        }finally {
            try {
                DataSourceUtils.commitAndRelease();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
        
        return isTransferSuncess;
    }

(4)da0层

public void out(String outStr, double money) throws SQLException {
        QueryRunner runner = new QueryRunner();
        String sql = "update account set money = money-? where name = ?";
        Object[] parm = {money,outStr};
        runner.update(DataSourceUtils.getConnection(),sql,parm);
        
    }

    public void in(String inStr, double money) throws SQLException {
        QueryRunner runner = new QueryRunner();
        String sql = "update account set money = money+? where name = ?";
        Object[] parm = {money,inStr};
        runner.update(DataSourceUtils.getConnection(),sql,parm);
        
    }
ThreadLocal存值

七 : 事务的特性与隔离级别

1事务的特性ACID

1)原子性(Atomicity)原子性是指事务是一个不可分割的工作单位,事务中的操作要么都发生,要么都不发生.
2)一致性(Consistency)一个事务中,事务前后数据的完整性必须保持一致.
3)隔离性(Isolation) 多个事务事务的隔离性是指多个用户并发访问数据库时,​一个用户的​事务不能被其它用户的事务所干扰,多个并发事务之间数据要相互隔离。

2并发访问问题----由隔离性引起

如果不考虑隔离性,事务存在3中并发访问问题。
1) 脏读:B事务读取到了A事务尚未提交的数据 ------ 要求B事务要读取A事​务提交的数据
2) 不可重复读:一个事务中两次读取的数据的内容不一致 ----- 要求的是一个事​务中多次读取时数据是一致的 --- update
3) 幻读/虚读:一个事务中 两次读取的数据的数量不一致 ----- 要求在一个事务多​次读取的数据的数量是一致的 --insert delete

3事务的隔离级别

1) read uncommitted : 读取尚未提交的数据 :哪个问题都不能解决
2) read committed:读取已经提交的数据 :可以解决脏读 ---- oracle默认的
3) repeatable read:重读读取:可以解决脏读 和 不可重复读 ---mysql默认的
4) serializable:串行化:可以解决 脏读 不可重复读 和 虚读---相当于锁表

注意:mysql数据库默认的隔离级别
查看mysql数据库默认的隔离级别:select @@tx_isolation
设置mysql的隔离级别:set session transaction isolation level 设置事务隔离级别

隔离级别的性能
​read uncommitted>read committed>repeatable read>serialazable
​安全性
​read uncommitted<read committed<repeatable read<serialazable

相关文章

  • Java篇-事务

    一 : 事务简述 一个事情由N个单元组成,N个组成单元同时成功,要不n个单元就同时失败,就是将N个组成单元放入一个...

  • Java中的事务——全局事务与本地事务

    在上一篇文章中说到过,Java事务的类型有三种:JDBC事务、JTA(Java Transaction API)事...

  • java事务

    1、java事务介绍 2、JDBC事务 3、JTA事务 1、java事务介绍 java事务分类:JDBC事务、...

  • 编辑 Java 中的事务 — JDBC 事务和 JTA 事务

    Java事务的类型有三种:JDBC事务、JTA(Java Transaction API)事务、容器事务。 常见的...

  • 分布式事务-3

    JTA/JTS Java Transaction API Java事务API(Java Transaction A...

  • SpringBoot使用Atomikos技术整合多数据源

    上一篇 << >> Atomikos是一个为Java平台提供增值服务的并且开源类事务管理器,如果将事务统一注册到A...

  • Java研发岗面试点解析(3)——数据库

    参考 Java 面试知识点解析(六)——数据库篇知名互联网公司校招 Java 开发岗面试知识点解析 1. 事务: ...

  • RoketMQ-事务消息

    1.事务消息执行流程 1.事务消息代码实现 Provider.java Consumer.java 工具类Rand...

  • Java事务

    [转]未找到出处.什么叫事务?Java如何处理事务呢? 什么叫事务? 这些就是数据库特有的术语了。懒虫在这里口头解...

  • java 事务

    事务:需要在同一个处理单元中执行一系列更新处理的集合。使用事务可以对数据库中的更新处理进行提交和取消。事务的特性:...

网友评论

      本文标题:Java篇-事务

      本文链接:https://www.haomeiwen.com/subject/qylmoftx.html