ThreadLocal本地线程的使用场景
当你使用数据库连接池想开启事务的时候是不是有点麻烦,今天我们来介绍一种使用本地线程ThreadLocal包装连接开启事务的方法,帮助我们更方便的开启事务,
下面我们看代码,因为我使用的是CP30的连接池,所以直接是从CP30里面获取的数据源
3 import java.sql.Connection; 4 import java.sql.SQLException; 5 6 public class MangerThreadLocalUtil { 7 //实例化一个本地线程对象 8 private static ThreadLocal<Connection> cl=new ThreadLocal<Connection>(); 9 //写一个获取Conn连接的方法 10 public static Connection getConnection(){ 11 //先从本地线程里面获取一个conn对象,如果没有就新建一个 12 Connection conn=cl.get(); 13 if(conn ==null){ 14 //因为我们所有的数据库连接操作都放进C3P0里面了,所以直接通过C3P0获取 15 conn=C3P0Utils.getConnection(); 16 //把这个新的Conn对象放入本地线程 17 cl.set(conn); 18 } 19 //如果不为空,只接返回一个Conn对象 20 return conn; 21 } 22 23 //开启事务的方法 24 public static void starTransAction(){ 25 try { 26 getConnection().setAutoCommit(false); 27 System.out.println("开启事务"); 28 } catch (SQLException e) { 29 e.printStackTrace(); 30 } 31 } 32 //提交事务的方法 33 public static void commitAction(){ 34 try { 35 getConnection().commit(); 36 } catch (SQLException e) { 37 e.printStackTrace(); 38 } 39 } 40 //回滚事务的方法 41 public static void getRollBack(){ 42 try { 43 getConnection().rollback(); 44 } catch (SQLException e) { 45 e.printStackTrace(); 46 } 47 } 48 }
使用这个技术的代码如下
1 public class OrderService { 2 //生成新订单 3 private OrderDao orderDao=new OrderDaoImpl(); 4 private OrderItemDao orderItemDao=new OrderItmeImpl(); 5 private ProductDao productDao=new ProductDaoImpl(); 6 public void createOrder(Order order){ 7 try { 8 9 //使用本地线程开启事务 10 MangerThreadLocalUtil.starTransAction(); 11 //插入订单表 12 orderDao.addOrder(order); 13 //插入订单详情 14 orderItemDao.addOrderItem(order.getItems()); 15 for (OrderItem o:order.getItems() 16 ) { 17 //减去库存 18 productDao.updatePnum(o.getProducts().getId(),o.getBuynum()); 19 } 20 //提交事务 21 MangerThreadLocalUtil.commitAction(); 22 System.out.println("订单添加成功"); 23 } catch (SQLException e) { 24 e.printStackTrace(); 25 //回滚事务 26 MangerThreadLocalUtil.getRollBack(); 27 } 28 29 }
使用注意事项
1.本地线程这个类里面的方法全都加上静态修饰也就是static这个修饰符,方便在使用的时候可以直接通过类名去调用方法
2.使用的话直接在sql语句没有执行以前用过类名去调用
3.用完后记得提交事务,还有在错误中回滚事务
浙公网安备 33010602011771号