zoukankan      html  css  js  c++  java
  • 用ThreadLocal管理事务

    1、适用场景

    一个service,操作两个dao,要求两个dao为同一个事务,要么全成功,要么全失败。

    DBUtils,使用ThreadLocal

     1 public class DbUtils {
     2     //线程局部数据容器
     3     private static ThreadLocal<Connection> tl = new ThreadLocal<Connection>();    
     4     private static DataSource ds;
     5     private static Connection conn;    
     6     static{
     7         ds=new ComboPooledDataSource();
     8     }
     9     
    10     public static DataSource getdDataSource()
    11     {
    12         return ds;
    13     }    
    14     public static Connection getcConnection()
    15     {
    16         
    17         try {            
    18             conn=tl.get();//是否已经有值
    19             if(conn==null)//没有值就添加
    20             {
    21                 conn=ds.getConnection();
    22                 tl.set(conn);
    23             }
    24             
    25         } catch (SQLException e) {
    26             e.printStackTrace();
    27         }
    28         return conn;
    29     }
    30     
    31     public static void remove()
    32     {
    33         tl.remove();//实现一个删除thredlocal中与线程相关的对象
    34     }    
    35 }

    过滤器中管理事务

     1 public void doFilter(ServletRequest request, ServletResponse response,
     2             FilterChain chain) throws IOException, ServletException {
     3         Connection conn = null;
     4         try {
     5             conn = DbUtils.getcConnection();
     6             conn.setAutoCommit(false);
     7             chain.doFilter(request, response);//放行
     8             conn.commit();//如果没有出错,提交事务,所以需要在dao中抛出异常,不能try-catch,否则无法捕捉到错误
     9             System.err.println("成功.......................");
    10         } catch (Exception e) {
    11             System.err.println("出错了......................");
    12             try {
    13                 //判断是否是数据库错误,如果不是还是提交
    14                 if (e instanceof SQLException) {
    15                     conn.rollback();
    16                 } else {
    17                     conn.commit();
    18                 }
    19             } catch (SQLException e1) {
    20                 e1.printStackTrace();
    21             }
    22         } finally {
    23             try {
    24                 conn.close();//关闭连接
    25                 DbUtils.remove();//实现一个删除thredlocal中与线程相关的对象
    26             } catch (SQLException e) {
    27                 e.printStackTrace();
    28             }
    29         }
    30     }

    注意:必须在dao中抛出异常,否则无法捕捉到,永远是提交事务。

     dao层:

    try {
                    DataSource ds=DbUtils.getdDataSource();
                    Connection conn=ds.getConnection();
                    QueryRunner run =new QueryRunner(ds);
                    String sql="INSERT INTO users VALUES (?,?,? ";
                    run.update(conn, sql,"U005","Tom","456");
                } catch (SQLException e) {                
                    throw new RuntimeException(e);
                }

    如果需要进行事务的管理,添加到过滤器url中即可

  • 相关阅读:
    AGC030 简要题解
    CF1601 简要题解
    CSP2021 题解
    2021.11.1-2021.11.7总结
    超快速梅森旋转SFMT(SIMD-oriented Fast Mersenne Twister)一览
    2021.10.25-2021.10.31总结
    CSP 2021 游记
    在Windows vs2015环境下编译使用Libevent
    在Windows环境下实现一个简单的libevent服务器
    Thinking in C++ 课后习题自己实现 第二章
  • 原文地址:https://www.cnblogs.com/liuwt365/p/4129585.html
Copyright © 2011-2022 走看看