zoukankan      html  css  js  c++  java
  • 使用动态代理实现数据库事务(转)

    数据库sql:

     1 create table T_USER
     2 (
     3    USER_ID              VARCHAR(10)            not null,
     4    USER_NAME            VARCHAR(30)            not null,
     5    PASSWORD             VARCHAR(20)            not null,
     6    CONTACT_TEL          VARCHAR(30),
     7    EMAIL                VARCHAR(30),
     8    CREATE_DATE          DATE,
     9    constraint P_KEY_1 primary key (USER_ID)
    10 );
    11 
    12 insert into t_user(user_id, user_name, password) values('root', '系统管理员', 'root');

    ConnectionManager.java(数据库连接管理)

     1 package dynamicProxyTransaction;
     2 
     3 import java.sql.Connection;
     4 import java.sql.DriverManager;
     5 import java.sql.SQLException;
     6 
     7 public class ConnectionManager {
     8     private ConnectionManager() {
     9     }
    10 
    11     private static ThreadLocal<Connection> threadConn = new ThreadLocal<Connection>();
    12 
    13     // 获取数据库连接
    14     public static Connection getConnection() {
    15         Connection conn = threadConn.get();
    16         if (conn == null) {
    17             try {
    18                 Class.forName("com.ibm.db2.jcc.DB2Driver");
    19                 conn = DriverManager.getConnection(
    20                         "jdbc:db2://127.0.0.1:50000/DRP", "db2admin", "619100");
    21             } catch (ClassNotFoundException e) {
    22                 e.printStackTrace();
    23             } catch (SQLException e) {
    24                 e.printStackTrace();
    25             }
    26             threadConn.set(conn);
    27         }
    28         return conn;
    29     }
    30 
    31     // 设置事务手动提交
    32     public static void benigTransction(Connection conn) {
    33         try {
    34             if (conn != null) {
    35                 if (conn.getAutoCommit()) {
    36                     conn.setAutoCommit(false);
    37                 }
    38             }
    39         } catch (SQLException e) {
    40             e.printStackTrace();
    41         }
    42     }
    43 
    44     // 提交事务
    45     public static void endTransction(Connection conn) {
    46         try {
    47             if (conn != null) {
    48                 if (!conn.getAutoCommit()) {
    49                     conn.commit();
    50                 }
    51             }
    52         } catch (SQLException e) {
    53             e.printStackTrace();
    54         }
    55     }
    56 
    57     // 设置Connection的原始状态
    58     public static void recoverTransction(Connection conn) {
    59         try {
    60             if (conn != null) {
    61                 if (conn.getAutoCommit()) {
    62                     conn.setAutoCommit(false);
    63                 } else {
    64                     conn.setAutoCommit(true);
    65                 }
    66             }
    67         } catch (SQLException e) {
    68             e.printStackTrace();
    69         }
    70     }
    71 
    72     // 发生异常回滚事务
    73     public static void rollback(Connection conn) {
    74         try {
    75             if (conn != null) {
    76                 conn.rollback();
    77             }
    78         } catch (SQLException e) {
    79             e.printStackTrace();
    80         }
    81     }
    82 
    83     // 关闭连接,并将其从当前线程删除
    84     public static void close() {
    85         Connection conn = threadConn.get();
    86         if (conn != null) {
    87             try {
    88                 conn.close();
    89                 conn = null;
    90                 threadConn.remove();
    91             } catch (SQLException e) {
    92                 e.printStackTrace();
    93             }
    94         }
    95     }
    96 }

    User.java(实体类)

     1 package dynamicProxyTransaction;
     2 
     3 import java.util.Date;
     4 
     5 public class User {
     6     // 用户ID
     7         private String id;
     8         // 用户名称
     9         private String name;
    10         // 登陆密码
    11         private String password;
    12         // 联系电话
    13         private String contact_tel;
    14         // 电子邮件
    15         private String email;
    16         // 用户创建日期
    17         private Date create_date;
    18 
    19         public String getId() {
    20             return id;
    21         }
    22 
    23         public void setId(String id) {
    24             this.id = id;
    25         }
    26 
    27         public String getName() {
    28             return name;
    29         }
    30 
    31         public void setName(String name) {
    32             this.name = name;
    33         }
    34 
    35         public String getPassword() {
    36             return password;
    37         }
    38 
    39         public void setPassword(String password) {
    40             this.password = password;
    41         }
    42 
    43         public String getContact_tel() {
    44             return contact_tel == null ? "" : contact_tel;
    45         }
    46 
    47         public void setContact_tel(String contact_tel) {
    48             this.contact_tel = contact_tel;
    49         }
    50 
    51         public String getEmail() {
    52             return email == null ? "" : email;
    53         }
    54 
    55         public void setEmail(String email) {
    56             this.email = email;
    57         }
    58 
    59         public Date getCreate_date() {
    60             return create_date;
    61         }
    62 
    63         public void setCreate_date(Date create_date) {
    64             this.create_date = create_date;
    65         }
    66 }

    UserDAO.java(用户相关的数据库操作)

    1 package dynamicProxyTransaction;
    2 
    3 import java.sql.SQLException;
    4 
    5 public interface UserDAO {
    6     public User selUser(String id ) throws SQLException ;
    7 }

    UserDAOImpl.java(UserDAO实现类)

     1 package dynamicProxyTransaction;
     2 
     3 import java.sql.Connection;
     4 import java.sql.PreparedStatement;
     5 import java.sql.ResultSet;
     6 import java.sql.SQLException;
     7 
     8 public class UserDAOImpl implements UserDAO {
     9     @Override
    10     public User selUser(String id) throws SQLException {
    11         ResultSet resu = null;
    12         String sql = "SELECT * FROM DB2ADMIN.T_USER WHERE USER_ID = ?";
    13         Connection conn = ConnectionManager.getConnection();
    14         PreparedStatement pstat = conn.prepareStatement(sql);
    15         User user = null;
    16         try {
    17             pstat.setString(1, id);
    18             resu = pstat.executeQuery();
    19             if (resu.next()) {
    20                 user = getUser(resu);
    21             }
    22         } finally {
    23             if (resu != null) {
    24                 resu.close();
    25             }
    26             if (pstat != null) {
    27                 pstat.close();
    28             }
    29         }
    30         return user;
    31     }
    32     // 获取用户
    33         private User getUser(ResultSet resu) throws SQLException {
    34             User user = new User();
    35             user.setId(resu.getString("USER_ID"));
    36             user.setName(resu.getString("USER_NAME"));
    37             user.setPassword(resu.getString("PASSWORD"));
    38             user.setContact_tel(resu.getString("CONTACT_TEL"));
    39             user.setEmail(resu.getString("EMAIL"));
    40             user.setCreate_date(resu.getTimestamp("CREATE_DATE"));
    41             return user;
    42         }
    43 }

    UserManager.java(用户管理功能定义)

    1 package dynamicProxyTransaction;
    2 
    3 public interface UserManager {
    4     public User findUser(String id ) throws Exception ;
    5 }

    UserManagerImpl.java(UserManager实现类)

     1 package dynamicProxyTransaction;
     2 
     3 import java.sql.SQLException;
     4 
     5 public class UserManagerImpl implements UserManager {
     6     // 这个和我以前写的不一样: 我都是写在每个方法中,写成属性应该好一点,减少创建对象的次数
     7     private UserDAO userDAO = null; 
     8 
     9     public UserManagerImpl() {
    10         userDAO = new UserDAOImpl();
    11     }
    12 
    13     public User findUser(String id) throws SQLException {
    14         return userDAO.selUser(id);
    15     }
    16 }

    TransactionProxy.java(代理实现)

     1 package dynamicProxyTransaction;
     2 
     3 import java.lang.reflect.InvocationHandler;
     4 import java.lang.reflect.InvocationTargetException;
     5 import java.lang.reflect.Method;
     6 import java.lang.reflect.Proxy;
     7 import java.sql.Connection;
     8 
     9 public class TransactionProxy implements InvocationHandler {
    10     private Object obj = null;
    11 
    12     // obj:需要代理的类
    13     public Object newProxyInstance(Object obj) {
    14         this.obj = obj;
    15         return Proxy.newProxyInstance(this.obj.getClass().getClassLoader(),
    16                 this.obj.getClass().getInterfaces(), this);
    17     }
    18 
    19     @Override
    20     public Object invoke(Object proxy, Method method, Object[] args)
    21             throws Throwable {
    22         // 用于接收参数
    23         Object param = null;
    24         // 如果是以下方法开头,则代理事务
    25         if (method.getName().startsWith("add")
    26                 || method.getName().startsWith("modify")
    27                 || method.getName().startsWith("find")
    28                 || method.getName().startsWith("del")) {
    29             Connection conn = ConnectionManager.getConnection();
    30             try {
    31                 // 手动提交事务
    32                 ConnectionManager.benigTransction(conn);
    33                 param = method.invoke(obj, args);
    34                 // 提交事务
    35                 ConnectionManager.endTransction(conn);
    36             } catch (Exception e) {
    37                 // 回滚事务
    38                 ConnectionManager.rollback(conn);
    39                 if (e instanceof InvocationTargetException) {
    40                     InvocationTargetException inv = (InvocationTargetException) e;
    41                     throw inv.getTargetException();
    42                 } else {
    43                     throw new Exception("操作失败!");
    44                 }
    45             } finally {
    46                 // 还原状态
    47                 ConnectionManager.recoverTransction(conn);
    48                 ConnectionManager.close();
    49             }
    50         }
    51         return param;
    52     }
    53 }

    Test.java(测试)

     1 package dynamicProxyTransaction;
     2 
     3 public class Test {
     4     public static void main(String[] args) throws Exception {
     5         TransactionProxy transctionProxy = new TransactionProxy();
     6 
     7         // //产生代理对象
     8         UserManager userManager = (UserManager) transctionProxy
     9                 .newProxyInstance(new UserManagerImpl());
    10         User user = userManager.findUser("root");
    11         System.out.println("用户名:" + user.getName());
    12     }
    13     
    14 }

    原文地址:http://itindex.net/detail/44008-java-%E4%BB%A3%E7%90%86-threadlocal

  • 相关阅读:
    BTRON 八十年代日本夭折的操作系统。
    zz白话说学计算机图形学
    陈怀临时间–浅谈微内核QNX/Neutrino
    java封装详解
    maven基础学习为什么要用maven,帮助解决了什么问题,怎么解决的,希望以后学习每个知识点都可以这样问下自己
    vscode开发vue,热更新
    Vue.js到前端工程化
    简洁好用的数据库表结构文档生成工具
    Java的修饰符
    1.谷粒商城000前言
  • 原文地址:https://www.cnblogs.com/caiyao/p/4783417.html
Copyright © 2011-2022 走看看