Tom给jerry汇款500元

1、如果多个操作,每个操作使用的是自己的单独的连接,则无法保证事务

2、具体步骤:
   1>事务开始操作前,开始事务:取消Connection的默认提交行为

2>如果事务的操作都成功,都提交事务
   3>回滚事务:若出现异常,则在catch块中回滚事务;

3、模板 try {
  
   //开始事务:取消默认提交(默认自动提交) con.setAutoCommit(false);
  
   //...
  
   
  //提交事务 con.commit();
  
  } catch (Exception e) {
  
  //...
  
 //如果出现异常就回滚事

try {

con.rollback();

} catch (SQLException e1) {
            e1.printStackTrace();

}

}

@Test
 public void testTransaction() {
  
    Connection con = null;
    try {

    con = JDBCTools.getConnection();
       System.out.println("默认事务:" + con.getAutoCommit());
       // 开始事务:取消默认提交(默认自动提交)
       con.setAutoCommit(false);
       String sql = "update users set balance=balance-500 where id=1";
       update(con, sql);
       int i = 10 / 0;
       sql = "update users set balance=balance+500 where id=2";
       update(con, sql);
       // 提交事务
       con.commit();

   } catch (Exception e) {
       // 如果出现异常就回滚事务
       try {
          con.rollback();
       } catch (SQLException e1) {
          e1.printStackTrace();
       }
    } finally {
       JDBCTools.release(null, null, con);
    }

}

设置事务的隔离级别

@Test
 public void testTransactionIsolationRead() {
  
  String sql = "select balance from users where id=1";
  Integer balance=getForValue(sql);
  System.out.println("balance="+balance);
 }

/*
  * 测试事务的隔离级别 在JDBC程序中可以通过Connection的setTransactionIsolation()方法 来设置事务的隔离级别
  */
 @Test
 public void testTransactionIsolationUpdate() {

Connection con = null;

try {

con = JDBCTools.getConnection();
   // 开始事务:取消默认提交(默认自动提交)
   con.setAutoCommit(false);
   String sql = "update users set balance=balance-500 where id=1";
   update(con,sql);
   con.commit();

} catch (Exception e) {
   e.printStackTrace();
  } finally {

}
 }

// 返回某个对象的属性值
 @SuppressWarnings("unchecked")
 public <E> E getForValue(String sql, Object... args) {

// 1、得到结果集:该结果集应该只有一行且只有一列
  Connection con = null;
  PreparedStatement ps = null;
  ResultSet rs = null;
  try {

con = JDBCTools.getConnection();
   //con.setTransactionIsolation(Connection.TRANSACTION_READ_UNCOMMITTED);
   con.setTransactionIsolation(Connection.TRANSACTION_READ_COMMITTED);
   ps = con.prepareStatement(sql);
   for (int i = 0; i < args.length; i++) {
    ps.setObject(i + 1, args[i]);
   }
   rs = ps.executeQuery();

if (rs.next()) {
    return (E) rs.getObject(1);
   }

} catch (Exception e) {
   e.printStackTrace();
  } finally {
   JDBCTools.release(rs, ps, con);
  }

// 2、取得结果集的
  return null;
 }

更新后的JDBCTools.java工具类如下:

import java.io.InputStream;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Properties;

/*
 * JDBC工具类
 * */
public class JDBCTools {

  // 提交事务
   public static void commit(Connection con) {

     if (con != null) {
         try {
            con.commit();
         } catch (SQLException e) {
            e.printStackTrace();
         }
      }
   }

  //回滚事务
   public static void rollback(Connection con) {

    if (con != null) {
         try {
            con.rollback();
           } catch (SQLException e) {
              e.printStackTrace();
           }
        }
   }
 
   //开始事务
   public static void beginTx(Connection con) {

     if (con != null) {
         try {
            con.setAutoCommit(false);
         } catch (SQLException e) {
            e.printStackTrace();
         }
      }
   }

   /*
    * 执行SQL的方法 insert,update,delete
    */
   public static void update(String sql, Object... args) {

     Connection conn = null;
      PreparedStatement ps = null;

     try {
         /*
          * 1、获取Connection连接 2、获取Statement 3、SQL语句 4、关闭数据库连接
          *
          */
         conn = getConnection();
         ps = conn.prepareStatement(sql);

      for (int i = 0; i < args.length; i++) {
            ps.setObject(i + 1, args[i]);
         }

        ps.executeUpdate();

    } catch (Exception e) {
         e.printStackTrace();
      } finally {
         release(null, ps, conn);
      }
   }

  public static Connection getConnection() throws Exception {

    String driverClass = null;
      String jdbcUrl = null;
      String user = null;
      String password = null;

    // 读取类路径下的jdbc.properties文件
      InputStream in = JDBCTools.class.getClassLoader().getResourceAsStream("jdbc.properties");
      Properties properties = new Properties();
      properties.load(in);

    driverClass = properties.getProperty("driver");
      jdbcUrl = properties.getProperty("jdbcUrl");
      user = properties.getProperty("user");
      password = properties.getProperty("password");
      // 加载数据库驱动程序
      Class.forName(driverClass);
      // 通过DriverManager的getConnection()方法获取数据库连接
      Connection connection = DriverManager.getConnection(jdbcUrl, user, password);
      return connection;

  }

  public static void release(ResultSet rs, Statement st, Connection conn) {

    if (rs != null) {
         try {
            rs.close();
         } catch (SQLException e) {
            e.printStackTrace();
         }
      }

     if (st != null) {
         try {
            st.close();
         } catch (SQLException e) {
            e.printStackTrace();
         }
      }

     if (conn != null) {
         try {
            conn.close();
         } catch (SQLException e) {
            e.printStackTrace();
         }
      }
   }
}

<十一>JDBC_事务的处理+隔离的更多相关文章

  1. 深入解析Mysql中事务的四大隔离级别及其所解决的读现象

    本文详细介绍四种事务隔离级别,并通过举例的方式说明不同的级别能解决什么样的读现象.并且介绍了在关系型数据库中不同的隔离级别的实现原理. 在DBMS中,事务保证了一个操作序列可以全部都执行或者全部都不执 ...

  2. Spring事务传播机制&隔离级别

    一.Propagation (事务的传播属性) Propagation : key属性确定代理应该给哪个方法增加事务行为.这样的属性最重要的部份是传播行为.有以下选项可供使用:PROPAGATION_ ...

  3. 数据库事务中的隔离级别和锁+spring Transactional注解

    数据库事务中的隔离级别和锁 数据库事务在后端开发中占非常重要的地位,如何确保数据读取的正确性.安全性也是我们需要研究的问题.ACID首先总结一下数据库事务正确执行的四个要素(ACID): 原子性(At ...

  4. Spring事务传播、隔离等级

    事务传播 PROPAGATION_REQUIRED 如果当前没有事务,就新建一个事务,如果已经存在一个事务中,加入到这个事务中.这是最常见的选择. PROPAGATION_SUPPORTS 支持当前事 ...

  5. mysql事务之间的隔离级别

    事务间未做隔离,会引起下面这些问题. 1.脏读:一个事务可读到另外一个尚未commit的事务中的数据. 2.不可重复读:在一个事务中,读取同一个数据 a,b,按顺序读取,在读a  b 之间,另外一个事 ...

  6. MySQL 笔记整理(8.b) --事务到底是隔离还是不隔离的?

    笔记记录自林晓斌(丁奇)老师的<MySQL实战45讲> (本篇内图片均来自丁奇老师的讲解,如有侵权,请联系我删除) 8.a) --事务到底是隔离还是不隔离的? 本周工作较忙,加上懒惰,拖更 ...

  7. MySQL 笔记整理(8.a) --事务到底是隔离还是不隔离的?

    笔记记录自林晓斌(丁奇)老师的<MySQL实战45讲> 8.a) --事务到底是隔离还是不隔离的? 这部分内容不太容易理解,笔者也是进行了多次阅读.因此引用原文: 之前有提到过,如果是在可 ...

  8. 数据库事务的四大特性以及事务的隔离级别-与-Spring事务传播机制&隔离级别

    数据库事务的四大特性以及事务的隔离级别   本篇讲诉数据库中事务的四大特性(ACID),并且将会详细地说明事务的隔离级别. 如果一个数据库声称支持事务的操作,那么该数据库必须要具备以下四个特性: ⑴ ...

  9. 框架源码系列十一:事务管理(Spring事务管理的特点、事务概念学习、Spring事务使用学习、Spring事务管理API学习、Spring事务源码学习)

    一.Spring事务管理的特点 Spring框架为事务管理提供一套统一的抽象,带来的好处有:1. 跨不同事务API的统一的编程模型,无论你使用的是jdbc.jta.jpa.hibernate.2. 支 ...

随机推荐

  1. 10分钟了解设计模式(C#)

    最近把<大话设计模式>重温了下(看完序才知道原来作者是也是博客园园友,这本书的最早博客版本在这里).体会最深的就是面向接口编程的重要性,如何在自己的项目中进行抽象,合理的利用各种设计模式. ...

  2. javascript中的对象

    除了字符串,数字,布尔值(true,false),null,undefined,js中的值都是对象. 操作一个对象 var o = {name: 'man', value: 99} o.name = ...

  3. 用 javassist 来修改 class 文件

    import javassist.ClassPool; import javassist.CtClass; import javassist.CtMethod; public class Test { ...

  4. Android MarginEnd与MarginStart (RTL)

    Android MarginLeft与MarginStart的区别http://blog.csdn.net/zhufuing/article/details/40181815 在写layout布局的时 ...

  5. [LINQ TO SQL]使用LINQ TO SQL创建数据库

    这篇博客将介绍如何使用LINQ TO SQL来创建数据库,以及如何映射Table之间的主外键关系. 我们的数据库表关系如下: Province与City之间1:M,City与Area之间1:M的关系. ...

  6. SOUI更新到2.0

    更新: 1.修改uiresbuilder,增加资源ID自动生成功能.包括自动提取所有布局中控件的name,自动生成ID,自动提取字符串表,颜色表.具体使用方式参见下一篇. 2.修改布局中引用字符串的方 ...

  7. linux 查看端口号

    在使用Linux系统的过程中,有时候会遇到端口被占用而导致服务无法启动的情况.比如HTTP使用80端口,但当启动Apache时,却发现此端口正在使用. 这种情况大多数是由于软件冲突.或者默认端口设置不 ...

  8. Linux 操作mysql数据库 创建库 导入、删除表

    确保线上的运行数据库是不可避免的本人小白,因公司上线没有办法自己去整服务器,深刻体会到服务器大神的霸气,所以为了增加记忆,服务广大员友记录一下 linux mysql 忘记root的密码无法登陆进my ...

  9. iOS应用九宫格算法

      1.框框横向间隔为:( "界面的总宽度"-"界面每行的控件的宽度" * "每行要现实的列数(这里是3)") / ("列数 + ...

  10. 浩瀚科技 定制现场无线手持打印PDA手持终端扫描条码开单解决方案

    PDA通过扫描商品条码移动开单,实现便携式办公,伴随式销售,是深圳市浩瀚技术有限公司的一款最新安卓微POS产品,PDA能通过WIFI无线局域网.GPRS互联网直接与主机电脑连接,让公司业务人员能随时随 ...