首页 > 代码库 > 用ThreadLocal管理事务

用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中即可

 

用ThreadLocal管理事务