JDBCTest10.java(该文件模拟读取数据库表信息)
1 package com.neu.jdbc; 2 3 import java.sql.Connection; 4 import java.sql.DriverManager; 5 import java.sql.PreparedStatement; 6 import java.sql.ResultSet; 7 import java.sql.SQLException; 8 9 /** 10 * 多线程访问同一个数据库中同一张表中相同的记录的时候,希望这些线程排队执行?有几种解决方案? 第一种解决方案: Java方面:sychronized 11 * 第二种解决方案: 数据库方面:隔离级别设置为串行化 第三种解决方案: SQL语句方面:悲观锁/行级锁 12 * 13 * 以下程序讲解行级锁: select……for update 以上DQL语句在事务没有结束之前,查询的记录被锁定,其他事务无权操作 数据安全机制 14 * 15 * @author imsha 16 * 17 */ 18 public class JDBCTest10 { 19 public static void main(String[] args) { 20 Connection conn = null; 21 PreparedStatement ps = null; 22 ResultSet rs = null; 23 try { 24 // 1、注册驱动 25 Class.forName("com.mysql.jdbc.Driver"); 26 // 获取连接对象 27 conn = DriverManager.getConnection("jdbc:mysql://localhost:3366/bjpowernode", "root", "123"); 28 29 // 2、开启事务 30 // 设置事务隔离级别 31 conn.setTransactionIsolation(Connection.TRANSACTION_READ_COMMITTED); 32 // 关闭自动提交机制 33 conn.setAutoCommit(false); 34 35 // 3、获取数据库操作对象 36 String sql = "select ename,job from emp where job=?"; 37 ps = conn.prepareStatement(sql); 38 ps.setString(1, "MANAGER"); 39 // 4、执行SQL语句 40 rs = ps.executeQuery(sql); 41 // 5、处理结果集 42 while (rs.next()) { 43 String ename = rs.getString("ename"); 44 String job = rs.getString("job"); 45 System.out.println("[" + ename + "," + job + "]"); 46 } 47 // 事务执行到此处,表示执行完成,应当手动提交 48 conn.commit(); 49 50 } catch (Exception e) { 51 // 若在以上事务执行过程中发生异常,则回滚 52 if (conn != null) { 53 try { 54 conn.rollback(); 55 } catch (SQLException e1) { 56 e1.printStackTrace(); 57 } 58 } 59 e.printStackTrace(); 60 } finally { 61 // 6、释放资源 62 if (rs != null) { 63 try { 64 rs.close(); 65 } catch (SQLException e) { 66 // TODO Auto-generated catch block 67 e.printStackTrace(); 68 } 69 } 70 if (conn != null) { 71 try { 72 conn.close(); 73 } catch (SQLException e) { 74 e.printStackTrace(); 75 } 76 } 77 if (ps != null) { 78 try { 79 ps.close(); 80 } catch (SQLException e) { 81 e.printStackTrace(); 82 } 83 } 84 } 85 } 86 }
JDBCTest11.java(该文件模拟的是对数据库表信息更新)
1 package com.neu.jdbc; 2 3 import java.sql.Connection; 4 import java.sql.DriverManager; 5 import java.sql.PreparedStatement; 6 import java.sql.SQLException; 7 8 public class JDBCTest11 { 9 public static void main(String[] args) { 10 Connection conn = null; 11 PreparedStatement ps = null; 12 13 try { 14 // 1、注册驱动 15 Class.forName("com.mysql.jdbc.Driver"); 16 // 2、获取连接对象 17 conn = DriverManager.getConnection("jdbc:mysql://localhost:3366/bjpowernode", "root", "123"); 18 conn.setTransactionIsolation(Connection.TRANSACTION_READ_COMMITTED); 19 conn.setAutoCommit(false); 20 // 3、获取预编译的数据库操作对象 21 String sql = "update emp set sal=? where job =?"; 22 ps = conn.prepareStatement(sql); 23 ps.setDouble(1, 3000.0); 24 ps.setString(2, "MANAGER"); 25 // 4、执行SQL语句 26 int count = ps.executeUpdate(sql); 27 System.out.println(count); 28 conn.commit(); 29 } catch (Exception e) { 30 // 若在以上事务执行过程中发生异常,则回滚 31 if (conn != null) { 32 try { 33 conn.rollback(); 34 } catch (SQLException e1) { 35 e1.printStackTrace(); 36 } 37 } 38 e.printStackTrace(); 39 } finally { 40 // 5、关闭资源 41 if (conn != null) { 42 try { 43 conn.close(); 44 } catch (SQLException e) { 45 e.printStackTrace(); 46 } 47 } 48 if (ps != null) { 49 try { 50 ps.close(); 51 } catch (SQLException e) { 52 e.printStackTrace(); 53 } 54 } 55 } 56 } 57 }
当Test10中执行到查询操作但未提交的时候,Test11中的更新操作无法进行,会发生阻塞