[Js-JDBC]行级锁(悲观锁)

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中的更新操作无法进行,会发生阻塞