2019独角兽企业重金招聘Python工程师标准>>>

事物:
1开启事务
2事务滚点
3提交事务
代码体现:
/*
 create database day19;
 create table account(
  id int primary key ,
  name varchar(100),
  money float
 )character set utf8 collate utf8_general_ci;
 insert into account values(1,'aaa',1000);
 insert into account values(2,'bbb',1000);
 insert into account values(3,'ccc',1000);
 */
public class TransactionDemo1 {
 @Test
 public void testTransaction(){
  Connection conn=null;
  PreparedStatement stmt=null;
  Savepoint sp=null;
  try{
   conn=JdbcUtil.getConnection();
   conn.setAutoCommit(false);//开启事物
   stmt=conn.prepareStatement("update account set money=money-100 where name='aaa'");
   stmt.executeUpdate();
   stmt=conn.prepareStatement("update account set money=money+100 where name='bbb'");
   stmt.executeUpdate();
   
   sp=conn.setSavepoint();//回滚点
   
  
   stmt=conn.prepareStatement("update account set money=money-100 where name='bbb'");
   stmt.executeUpdate();
   int i=1/0;
   stmt=conn.prepareStatement("update account set money=money+100 where name='ccc'");
   stmt.executeUpdate();
  conn.commit();
  }catch(Exception e){
   e.printStackTrace();
   try {
    if(conn!=null){
    conn.rollback(sp);
    }else{
     conn.rollback();
    }
   } catch (SQLException e1) {
    e1.printStackTrace();
   }
  }finally{
   try {
    conn.commit();
   } catch (SQLException e) {
    e.printStackTrace();
   }
   JdbcUtil.release(null, stmt, conn);
  }
 }
}

模拟连接池:
public class SimpleConnectionPool {
 private static LinkedList<Connection> pool=new LinkedList<Connection>();
 static{
  //连接池初始化
  try {
   for(int i=0;i<10;i++){
    pool.add(JdbcUtil.getConnection());
   }
  } catch (Exception e) {
   throw new ExceptionInInitializerError("连接池初始化失败");
  }
 }
 public synchronized static Connection getConnection(){
  if(pool.size()>0){
   return pool.removeFirst();
  }else{
   throw new RuntimeException("服务器正忙");
  }
 }
 public static void release(Connection conn){
  pool.addLast(conn);

事物的隔离级别:
1、事务的特性:(面试题)
原子性:处于同一个事务中的多条语句,要么全都成功,要么全都不成成功。
一致性:事务必须使数据库从一个一致性状态变换到另外一个一致性状态。比如转账:转账前a+b=2000,转账后a+b=2000
隔离性:多线程并发时,一个事务不能被其他事务所干扰。
持久性:数据应该被永久性的保存起来。(硬盘,而不是内存)
ACID
2、事务的隔离性专题
如果不考虑事务的隔离性,会导致以下不正确的问题:
a、脏读:指一个事务读到了另外一个事务中未提交的数据
b、不可重复读:指一个事务读到了另外一个事务update后(事务提交了)的数据
c、虚读:指一个事务读到了另外一个事务insert的数据

3、演示操作:
3.1数据库控制隔离级别相关的语句(必须用在事务之中):

数据库有四个隔离级别:
READ UNCOMMITTED:脏读、不可重复读、虚读都有可能发生。
READ COMMITTED:防止脏读发生;不可重复读、虚读都有可能发生。
REPEATABLE READ:(MySQL默认级别)防止脏读、不可重复读;虚读有可能发生。
SERIALIZABLE:防止脏读、不可重复读、虚读的发生

特点:从上到下,隔离级别越高,数据越安全,但是效率越低

select @@tx_isolation;  查看当前数据库的隔离级别
set transaction isolation level 四个级别之一;更改当前事务的隔离级别

代码体现:
public class TxIsolationDemo {
 @Test
 public void test(){
  Connection conn = null;
  PreparedStatement stmt = null;
  ResultSet rs = null;
  try{
   conn = JdbcUtil.getConnection();
   conn.setTransactionIsolation(Connection.TRANSACTION_READ_COMMITTED);//只能防止脏读的发生.注意,一定要放在开始事务之前
   conn.setAutoCommit(false);//开启事务
   //查询aaa账户的余额
   stmt = conn.prepareStatement("select * from account where name='aaa'");
   rs = stmt.executeQuery();
   if(rs.next()){
    System.out.println("第一次查询:"+rs.getString("money"));
   }
   
   //在查询aaa账户的余额
   stmt = conn.prepareStatement("select * from account where name='aaa'");
   rs = stmt.executeQuery();
   if(rs.next()){
    System.out.println("第二次查询:"+rs.getString("money"));
   }
   conn.commit();
  }catch(Exception e){
   if(conn!=null){
    try {
     conn.rollback();
    } catch (SQLException e1) {
     e1.printStackTrace();
    }
   }
   e.printStackTrace();
  }finally{
   JdbcUtil.release(rs, stmt, conn);
  }
 }
}

基于接口的动态代理:
静态代理:
代码体现:
接口:

public interface Human {
 void sing(float money);
 void dance(float money);
}

歌手类:
public class SpringBrother implements Human {
 public void sing(float money){
  System.out.println("开始唱歌"+money);
 }
 public void dance(float money){
  System.out.println("开始跳舞"+money);
 }
}
代理人类:
public class ProxyMan {
 private SpringBrother sb=new SpringBrother();
 public void sing(float money){
  if(money>1000){
   money=money/2;
   sb.sing(money);
  }else{
   throw new RuntimeException("出场费不得低于1000");
  }
 }
 public void dance(float money){
  if(money>1000){
   money=money/2;
   sb.dance(money);
  }else{
   throw new RuntimeException("出场费不得低于1000");
  }
 }
 
}
客户类:
public class Client {
 private static ProxyMan pm=new ProxyMan();
 public static void main(String[] args) {
  pm.sing(2000);
  pm.dance(2000);
 }
}

动态代理:(在内存中生成代理类或者代理类的实例)
1:基于接口的动态代理
public class Client {
 
 
 public static void main(String[] args) {
  final Human h=new SpringBrother();//原有对象
  Human hMan=(Human)Proxy.newProxyInstance(h.getClass().getClassLoader(), h.getClass().getInterfaces(), new InvocationHandler() {
   //匿名内部类实现接口
   //所有调用被代理类对象的方法,都会经过该方法
   /**
    * Object proxy:代理对象本身的引用
    * Method method:当前调用的是哪个方法
    * Object[] args:当前调用的方法用到的参数
    */
   public Object invoke(Object proxy, Method method, Object[] args)
     throws Throwable {
    String metnodName=method.getName();
    if("sing".equals(metnodName)){
     float money=(Float) args[0];
     if(money>1000){
      money=money/2;
      h.sing(money);
     }else{
      throw new RuntimeException("出场费不得低于1000");
     }
    }else if("dance".equals(metnodName)){
     float money=(Float) args[0];
     if(money>1000){
      money=money/2;
      h.dance(money);
     }else{
      throw new RuntimeException("出场费不得低于1000");
     }
    }
    return null;
   }
  });
  hMan.sing(10000);
  hMan.dance(10000);
 }
}

2:基于子类的动态代理:
person类:
public class Person {
 public void m1(){
  System.out.println("方法m1执行了");
 }
}
贷代码体现:

public class PersonDemo {
 public static void main(String[] args) {
  final Person p=new Person();
  Person pp=(Person)Enhancer.create(p.getClass(), new MethodInterceptor(){

public Object intercept(Object proxy, Method method, Object[] arg2,
     MethodProxy arg3) throws Throwable {
    long time=System.nanoTime();
    Object obj=method.invoke(p, arg2);
    System.out.println(method.getName()+"运行了"+(System.nanoTime()-time));
    return obj;
   }
   
  });
  pp.m1();
 }
}

动态代理实现close方法的改变:
public class MyDataSource3 implements DataSource {
 private static List<Connection> pool = new ArrayList<Connection>();
 static {
  try {
   for (int i = 0; i < 10; i++) {
    Connection conn = JdbcUtil.getConnection();
    pool.add(conn);
   }
  } catch (Exception e) {
   throw new ExceptionInInitializerError(e);
  }
 }

// 获取链接
 public synchronized Connection getConnection() throws SQLException {
  if (pool.size() > 0) {
   final Connection conn = pool.remove(0);// com.mysql.jdbc.COnnection
   Connection proxyConn = (Connection) Proxy.newProxyInstance(conn
     .getClass().getClassLoader(), conn.getClass()
     .getInterfaces(), new InvocationHandler() {
    public Object invoke(Object proxy, Method method, Object[] args)
      throws Throwable {
     //如果用户调用的是close方法,把链接还回池中。其他方法,用原有对象的
     if("close".equals(method.getName())){
      System.out.println("你调用的是close,还回池中");
      return pool.add(conn);
     }else{
      System.out.println("调用的其他方法,什么都没做");
      return method.invoke(conn, args);
     }
     
    }
   });
   return proxyConn;
  } else {
   throw new RuntimeException("服务器真忙");
  }
 }

@Override
 public PrintWriter getLogWriter() throws SQLException {
  // TODO Auto-generated method stub
  return null;
 }

@Override
 public void setLogWriter(PrintWriter out) throws SQLException {
  // TODO Auto-generated method stub

}

@Override
 public void setLoginTimeout(int seconds) throws SQLException {
  // TODO Auto-generated method stub

}

@Override
 public int getLoginTimeout() throws SQLException {
  // TODO Auto-generated method stub
  return 0;
 }

@Override
 public <T> T unwrap(Class<T> iface) throws SQLException {
  // TODO Auto-generated method stub
  return null;
 }

@Override
 public boolean isWrapperFor(Class<?> iface) throws SQLException {
  // TODO Auto-generated method stub
  return false;
 }

@Override
 public Connection getConnection(String username, String password)
   throws SQLException {
  // TODO Auto-generated method stub
  return null;
 }

}

转载于:https://my.oschina.net/u/1589656/blog/288646

事务,动态代理,连接池相关推荐

  1. 做了一个动态代理 IP 池项目,邀请大家免费测试~

    长期在掘金潜水, 现在打算出来创业了,目前公司在深圳. 做了点啥呢, 就是给爬虫用的动态代理 IP 池啦. 目前运行很稳定, 邀请大家来免费测试使用, 获取免费激活码:微信公众号"2808p ...

  2. 数据库MySQL基础---事务相关特性--连接池DBCP--C3P0--JavaBean--DBUtils工具

    事务相关特性–连接池DBCP–C3P0–JavaBean–DBUtils工具 事务的概念 事务(Transaction),一般是指要做的或所做的事情.在计算机术语中是指访问并可能更新数据库中各种数据项 ...

  3. 通过Python利用ADSL服务器和tinyproxy构建数据自己的动态代理IP池,用django+redis做web服务,提供IP接口

    应公司业务需求需要在一些地方使用代理,要求连通率高,速度快,最主要的还要便宜,对比多家供应商后,最后还是决定自购拨号服务搭建代理IP池. 需要配置:1.一台或多台adsl服务器(用以提供IP,可网上购 ...

  4. 通过Python利用ADSL服务器和tinyproxy构建数据自己的动态代理IP池,用django+redis做web服务 (优化版)

    代理池初始版:https://blog.csdn.net/MeteorCountry/article/details/82085238 上一篇文章中所搭建的代理池在使用过程中出现了点小问题,代理池中莫 ...

  5. spring——事务动态代理造成属性为null

        近日遇到一个很诡异的问题,kotlin的一段老代码莫名其妙报空指针,而且只有整个springboot项目起起来才会报错,如果写单元测试时单独注入几个类,是不会报错的.最终锁定原因是因为在原本的 ...

  6. JAVA→JDBCJava DataBase Connectivity、存储过程Stored Procedure、事务Transaction、连接池DBCP C3P0、JDBC升级替代框架

    致虚极,守静笃. 万物并作,吾以观其复. 夫物芸芸,各复归其根. 归根曰静,是谓复命. 复命曰常,知常曰明. 不知常,妄作凶. 知常容,容乃公,公乃全,全乃天,天乃道,道乃久,没身不殆. ----&l ...

  7. SpringBoot2/SpringBoot/Java动态数据源配置、动态连接池配置、多数据源负载均衡

    Java动态数据源配置.动态连接池配置.多数据源负载均衡 大家好,今天给大家推荐一个自产的连接池插件.废话不多说,本文接口分为以下主题: 1. 插件开发背景: 2. 插件提供的能力: 3. 插件的使用 ...

  8. sqlserver连接池及查看连接数相关

    sqlserver连接池及查看连接数相关 asp.net 连接池 数据库链接是一种危险的.昂贵的.有限的资源,特别是在多层Web应用程序中.你必须正确管理你的链接,因为你的方法将极大的影响应用程序的整 ...

  9. Lettuce连接池

    Lettuce 连接被设计为线程安全,所以一个连接可以被多个线程共享,同时lettuce连接默认是自动重连.虽然连接池在大多数情况下是不必要的,但在某些用例中可能是有用的.lettuce提供通用的连接 ...

  10. [转].Net连接池超时注意事项

    http://blog.csdn.net/jxqvip/article/details/6738551 超时时间已到.超时时间已到,但是尚未从池中获取连接.出现这种情况可能是因为所有池连接均在使用,并 ...

最新文章

  1. 【ACM】LightOJ - 1008 Fibsieve`s Fantabulous Birthday (找规律,找...)
  2. 随机数的产生可用于的场景验证码 密码
  3. 使用iCarousel的旋转木马效果请求图片
  4. 一个静态库框架模板: iOS Universal Framework Mk 7
  5. flink sql设置并行度_《从0到1学习Flink》—— Flink parallelism 和 Slot 介绍
  6. linux多cpu运行python脚本,linux系统使用python获取cpu信息脚本分享
  7. 可运行的C语言程序的拓展名,可运行的c语言程序的扩展名为什么?
  8. silverlight异常
  9. 初学编程丨从零开始学习编程的基本路线,BAT程序员亲手总结!
  10. mysql字符串拼接有空值_mysql字符串如何拼接并设置null值 mysql字符串拼接并设置null值实例方法...
  11. Linux下原生异步IO接口Libaio的用法
  12. 二叉树的学习:前中后序遍历方法
  13. 新版谷歌浏览器开启Flash支持,开启flash方法
  14. 《深入理解计算机系统》实验二Bomb Lab下载和官方文档机翻
  15. 耗时十个月的德国APS,教会我的学习方法
  16. 【LeetCode】数据库部分的题目及答案汇总
  17. 软件测试中 Bug 书写规范
  18. spark错误ERROR LiveListenerBus: SparkListenerBus has already stopped!
  19. 刘桉齐:敏捷回顾会七步成诗法 | 真北群友作品
  20. 海信电视版本系统升级服务器地址,海信电视系统版本太低怎么升级?

热门文章

  1. Oracle 当前用户给另一个用户授权查询指定表或视图的权,否则另一个用户提示不存在视图或表
  2. tomcat 如何配置环境变量
  3. swift中没有selectall的解决
  4. Javascript基础之-强制类型转换(三)
  5. 浏览器兼容性问题——IE不支持却很实用的CSS属性Outline和Child
  6. IOS中设置圆角图片
  7. iOS: 教你给UI控件添加Badge(消息提醒小圆点)
  8. 自动化运维工具puppet(四)
  9. oracle group by
  10. 数据结构与算法 —— 基础一(排列组合)