使用动态代理实现数据库事务

数据库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 @Override10 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 @Override20 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 }

相关文章