zoukankan      html  css  js  c++  java
  • 事务

    事务概述

      一件事情有n个组成单元 要不这n个组成单元同时成功 要不n个单元就同时失败

    就是将n个组成单元放到一个事务中

    MySQL的事务

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

    手动事务:

    1)显示的开启一个事务:start transaction

    2)事务提交:commit代表从开启事务到事务提交 中间的所有的sql都认为有效 真正的更新数据库

    3)事务的回滚:rollback 代表事务的回滚 从开启事务到事务回滚 中间的所有的   sql操作都认为无效数据库没有被更新

    JDBC事务操作

    默认是自动事务:

      执行sql语句:executeUpdate()  ---- 每执行一次executeUpdate方法 代表     事务自动提交

    通过jdbc的API手动事务:

      开启事务:conn.setAutoComnmit(false);

      提交事务:conn.commit();

      回滚事务:conn.rollback();

    注意:控制事务的connnection必须是同一个

      执行sql的connection与开启事务的connnection必须是同一个才能对事务进行控制

    例子:

    package com.oracle.demo01;
    
    import java.sql.Connection;
    import java.sql.DriverManager;
    import java.sql.PreparedStatement;
    import java.sql.SQLException;
    
    public class JDBCDemo {
        public static void main(String[] args) {
            Connection conn=null;
            try {
                //1.注册驱动
                Class.forName("com.mysql.jdbc.Driver");
                //2.获得链接
                String url="jdbc:mysql://localhost:3306/bank?characterEncoding=utf8";
                String user="root";
                String password="123456";
                conn=DriverManager.getConnection(url, user, password);
                //开启事务(手动开启事务)
                conn.setAutoCommit(false);
                //3.获得语句执行平台
                String sql=" update account set money=3000 where aname=?";
                PreparedStatement pst=conn.prepareStatement(sql);
                //执行
                pst.setString(1, "xiaoliang");
    //            int y=1/0;
                pst.executeUpdate();
                //提交事务
                conn.commit();
                pst.close();
                conn.close();
            } catch (ClassNotFoundException | SQLException e) {
                // TODO Auto-generated catch block
                //事务回滚
                try {
                    conn.rollback();
                } catch (SQLException e1) {
                    // TODO Auto-generated catch block
                    e1.printStackTrace();
                }
                e.printStackTrace();
            }
            
        }
    }

    DBUtils事务操作

    QueryRunner

    有参构造:QueryRunner runner = new QueryRunner(DataSource dataSource);

      有参构造将数据源(连接池)作为参数传入QueryRunner,QueryRunner会从连 接池中获得一个数据库连接资源操作数据库,所以直接使用无Connection参数  的update方法即可操作数据库

    无参构造:QueryRunner runner = new QueryRunner();

      无参的构造没有将数据源(连接池)作为参数传入QueryRunner,那么我们在使   用QueryRunner对象操作数据库时要使用有Connection参数的方法

    package com.oracle.demo01;
    
    import java.sql.Connection;
    import java.sql.SQLException;
    
    import org.apache.commons.dbutils.QueryRunner;
    
    import com.oracle.tools.DBUtils;
    import com.oracle.tools.JDBCutils;
    
    public class DBUtilsDemo {
        public static void main(String[] args) {
            QueryRunner qr=new     QueryRunner();
            Connection conn=JDBCutils.getConn();
            
            String sql=" update account set money=10 where aname=?";
            try {
                //开启事务
                conn.setAutoCommit(false);
            
                qr.update(conn,sql,"xiaoliang");
    //            int y=1/0;
                //提交事务
                conn.commit();
            } catch (SQLException e) {
                
                //事务回滚
                try {
                    conn.rollback();
                } catch (SQLException e1) {
                    
                    e1.printStackTrace();
                }
                e.printStackTrace();
            }
        }
    }

    事物的特性和隔离级别

    事务的特性ACID

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

         2)一致性(Consistency)一个事务中,事务前后数据的完整性必须保持一致。

         3)隔离性(Isolation)多个事务,事务的隔离性是指多个用户并发访问数据库时, 一个用户的 事务不能被其它用户的事务所干扰,多个并发事务之间数据要相互隔离。

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

    事务例子:转账

    dao层

    package com.oracle.dao;
    
    import java.sql.Connection;
    import java.sql.SQLException;
    
    import org.apache.commons.dbutils.QueryRunner;
    
    import com.oracle.tools.DBUtils;
    
    public class TransferDao {
        public void increaseMoney(String in,double money) throws SQLException{
            QueryRunner qr=new     QueryRunner();
        Connection conn=DBUtils.getCurrentConnection();
            String sql=" update account set money=money+?  where aname=?";
            qr.update(conn,sql,money,in);
            
        }
        public void unincreaseMoney(String out,double money) throws SQLException{
            QueryRunner qr=new     QueryRunner();
            Connection conn=DBUtils.getCurrentConnection();
            String sql=" update account set money=money-?  where aname=?";
            qr.update(conn,sql,money,out);
            
        }
    }

    service层

    package com.oracle.service;
    
    import java.sql.Connection;
    import java.sql.SQLException;
    
    import com.oracle.dao.TransferDao;
    import com.oracle.tools.DBUtils;
    
    public class TransferService {
        private TransferDao transferdao=new TransferDao();
        public boolean transfer(String in,String out,double money){
            boolean isTransferSuccess=true;
            try {
                //开启事务
                DBUtils.start();
    //            int a=1/0;
                transferdao.increaseMoney(in, money);
                transferdao.unincreaseMoney(out, money);
                //提交事务
                DBUtils.commit();
            } catch (Exception e) {
                isTransferSuccess=false;
                //回滚事务
                    DBUtils.rollback();
                e.printStackTrace();
            }
            
            return isTransferSuccess;
            
        }
    }

    tools层-DBUtils

    package com.oracle.tools;
    
    import java.sql.Connection;
    import java.sql.SQLException;
    
    import javax.sql.DataSource;
    
    import org.apache.commons.dbcp.BasicDataSource;
    
    public class DBUtils {
        public static final String DRIVER = "com.mysql.jdbc.Driver";
        public static final String URL = "jdbc:mysql://localhost:3306/bank?characterEncoding=utf8";
        public static final String USERNAME = "root";
        public static final String PASSWORD = "123456";
        public static ThreadLocal<Connection> tl=new ThreadLocal<Connection>();
        
        /*
         * 创建连接池BasicDataSource
         */
        public static BasicDataSource dataSource = new BasicDataSource();
        //静态代码块
        static {
            //对连接池对象 进行基本的配置
            dataSource.setDriverClassName(DRIVER); // 这是要连接的数据库的驱动
            dataSource.setUrl(URL); //指定要连接的数据库地址
            dataSource.setUsername(USERNAME); //指定要连接数据的用户名
            dataSource.setPassword(PASSWORD); //指定要连接数据的密码
        }
        /*
         * 返回连接池对象
         */
        public static DataSource getDataSource(){
            return dataSource;
        }
        public static Connection getCurrentConnection(){
            Connection conn=tl.get();
            if(conn==null)
            {    
                //第一种
                conn=getConn();
                tl.set(conn);
                //第二种,
    //            tl.set(getConn());
    //            conn=tl.get();
            
            }
            return conn;
        }
        //开启事务
        public static void start(){
            try {
                getCurrentConnection().setAutoCommit(false);
            } catch (SQLException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
        //提交事务
        public static void commit(){
            try {
                getCurrentConnection().commit();
            } catch (SQLException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
        //回滚事务
        public static void rollback(){
            try {
                getCurrentConnection().rollback();
            } catch (SQLException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
        //连接对象
    public static Connection getConn(){
        Connection conn=null;
        try {
            conn=dataSource.getConnection();
        } catch (SQLException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return conn;
    }
    
    }

    web层

    package com.oracle.web;
    
    import java.io.IOException;
    import javax.servlet.ServletException;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    
    import com.oracle.service.TransferService;
    
    public class TransferServlet extends HttpServlet {
    private TransferService transferservice=new TransferService();
        public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            
            request.setCharacterEncoding("utf-8");
            String out=request.getParameter("out");
            String in=request.getParameter("in");
            double money=Double.parseDouble(request.getParameter("money"));
            //数值类型强转:byte>short>int>long>float>double
            //int a=(int)2.9;
            //向下转型:Object obj=new Person();Person p=(Person)obj;
            boolean flag=transferservice.transfer(in, out, money);
            response.setContentType("text/html;charset=utf-8");
            if(flag){
                response.getWriter().write("转账成功");
            
            }else{
                response.getWriter().write("转账失败");
            }
            
        }
    
        public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            doGet(request, response);
        }
    }

    转账jsp页面

    <%@ page language="java" contentType="text/html; charset=UTF-8"
        pageEncoding="UTF-8"%>
    <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
    <html>
    <head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    <title>Insert title here</title>
    </head>
    <body>
    <form action="${pageContext.request.contextPath }/TransferServlet" method="post">
    转出用户:<input type="text" name="out"><br>
    转入用户<input type="text" name="in"><br>
    金额:<input type="text" name="money"><br>
    <input type="submit" value="提交"><br>
    
    </form>
    </body>
    </html>
  • 相关阅读:
    bzoj 1030 [JSOI2007]文本生成器
    Swift 学习笔记 (闭包)
    Swift 学习笔记 (函数)
    HTML 学习笔记 JQueryUI(Interactions,Widgets)
    HTML 学习笔记 JQuery(表单,表格 操作)
    HTML 学习笔记 JQuery(animation)
    HTML 学习笔记 JQuery(盒子操作)
    HTML 学习笔记 JQuery(事件)
    HTML 学习笔记 JQuery(DOM 操作3)
    HTML 学习笔记 JQuery(DOM 操作2)
  • 原文地址:https://www.cnblogs.com/lzw123-/p/9764715.html
Copyright © 2011-2022 走看看