使用JDBC演示悲观锁

首先什么是悲观锁呢?
如果一个查询语句后面加了for update,例如select * from emp where job = ‘MANAGER’ for update;,当这个SQL语句执行的时候,在事务没有结束之前,job = 'MANAGER’的记录会被锁定,其他事务不能对job = 'MANAGER’进行update操作,这种机制被称为“行级锁”,也被称为悲观锁,锁定的是表中的某些行数据,注意数据库的存储引擎需要使用InnoDB方式;既然说到了悲观锁,这里也说一下乐观锁,乐观锁是可以使用版本号的方式来实现,就是给表上设置一个版本号,多个事务同时进行,当其中一个事务完成之后就会把版本号改变,然后其他的事务在提交的时候发现版本号改变了,就会回滚,这个就是乐观锁,对比来看,悲观锁就是我锁住了,谁都不能动这些记录,而乐观锁是大家都可以动,谁的速度快谁就可以执行命令
使用for update的悲观锁代码

public class PessimisticLOCK {
    public static void main(String[] args) {
        Connection conn = null;
        PreparedStatement ps = null;
        ResultSet res = null;

        try {
            ResourceBundle rb = ResourceBundle.getBundle("resource/db");
            // 1、注册驱动
            String driver = rb.getString("driver");
            Class.forName(driver);

            // 2、获取连接
            String url = rb.getString("url");
            String user =  rb.getString("user");
            String password = rb.getString("password");
            conn = DriverManager.getConnection(url, user,password );
            conn.setAutoCommit(false);// 设置事务提交方式是手动提交

            // 3、获取预编译的数据库操作对象
            String sql = "select * from emp where job = ? for update";
            ps = conn.prepareStatement(sql);
            ps.setString(1, "MANAGER");

            // 4、执行SQL
            res = ps.executeQuery();

            // 5、处理查询结果集
            while (res.next()){
                System.out.println(res.getString("ename")+","+res.getString("sal"));
            }

            conn.commit();// 如果没有出现异常,就提交事务
        } catch (ClassNotFoundException e) {
            if (conn!=null){
                try {
                    conn.rollback();// 如果出现异常,就回滚事务
                } catch (SQLException e1) {
                    e1.printStackTrace();
                }
            }
            e.printStackTrace();
        } catch (SQLException e) {
            e.printStackTrace();
        } finally {
            if (res!=null){
                try {
                    res.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }
            if (ps!=null){
                try {
                    ps.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }
            if (conn!=null){
                try {
                    conn.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

验证悲观锁的更新代码:

public class CheckLock {
    public static void main(String[] args) {
        Connection conn = null;
        PreparedStatement ps = null;

        try {
            ResourceBundle rb = ResourceBundle.getBundle("resource/db");
            // 1、注册驱动
            String driver = rb.getString("driver");
            Class.forName(driver);

            // 2、获取连接
            String url = rb.getString("url");
            String user =  rb.getString("user");
            String password = rb.getString("password");
            conn = DriverManager.getConnection(url, user,password );
            conn.setAutoCommit(false);// 设置事务提交方式是手动提交

            // 3、获取预编译的数据库操作对象
            String sql = "update emp set sal=sal*2 where job = ?";
            ps = conn.prepareStatement(sql);
            ps.setString(1, "MANAGER");

            // 4、执行SQL
            int i = ps.executeUpdate();

            System.out.println("更新了"+i+"条");

            conn.commit();// 如果没有出现异常,就提交事务
        } catch (ClassNotFoundException e) {
            if (conn!=null){
                try {
                    conn.rollback();// 如果出现异常,就回滚事务
                } catch (SQLException e1) {
                    e1.printStackTrace();
                }
            }
            e.printStackTrace();
        } catch (SQLException e) {
            e.printStackTrace();
        } finally {
            if (ps!=null){
                try {
                    ps.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }
            if (conn!=null){
                try {
                    conn.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

解释:
在第一个代码中的commit()方法上面设立断点,采用Debug方式运行程序,然后在运行第二个代码,发现第二个代码在等待,然后让第一个代码执行完成,然后第二个代码也会随后执行完成

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值