0
回答
Java 操作 Mysql,借书问题
利用AWS快速构建适用于生产的无服务器应用程序,免费试用12个月>>>   
  for (int i = 0; i < 10; i++) {
            new Thread(new Runnable() {
                @Override
                public void run() {
                    Connection connection = null;
                    PreparedStatement preparedStatement = null;
                    try {
                        connection = DbUtil.getConnection();
                        connection.setAutoCommit(false);
                        connection.setTransactionIsolation(Connection.TRANSACTION_SERIALIZABLE);

                        preparedStatement = connection.prepareStatement("select status FROM ttp WHERE id=10293313");
                        ResultSet resultSet = preparedStatement.executeQuery();


                        if (resultSet.next()) {
                            int channel = resultSet.getInt("channel_1");
                            if (channel > 0) {
                                preparedStatement = connection.prepareStatement("update ttp set status=status-1 WHERE  id=10293313");
                                preparedStatement.executeUpdate();
                            }
                        }
                        connection.commit();
                    } catch (Exception ex) {
                        ex.printStackTrace();
                        try {
                            connection.rollback();
                        } catch (Exception e) {
                            e.printStackTrace();
                        }
                    } finally {
                        DbUtil.closeSource(null, preparedStatement, connection);
                    }
                }
            }).start();

        }

上面代码是Java操作MySQL 的一段代码,大致是这样的。

1. 不自动提交事务

2. 隔离级别设置的是最高

3. 先查找ID为10293313status字段是否为0

4. 如果大于0就减一

5. 开启四个线程执行上述操作

结果:

    1. 出现死锁,报异常com.mysql.jdbc.exceptions.jdbc4.MySQLTransactionRollbackException: Deadlock found when trying to get lock; try restarting transaction

    2. 其他隔离级别,执行过后 status会小于0,序列化隔离级别虽然不会出现小于0 的情况,但是会报异常。

问:

    1. 原本以为,设置成序列化隔离级别,事务之间是串行执行的,但是实际上好像并不是,这是什么情况?多个强制设置成串行隔离级别的读操作好像也是并行执行的?

    2. 如何实现上面的需求,在并发情况下,先读取,如果不满足情况就不更新,满足情况就更新?

    3. 在MySQL主从读写分离的时候,会出现同步延迟,上面的情况可能会更加严重,会不会出现过个线程都读取到1,都更新的时候最后变成负数的情况,如何解决?


以上可能存在概念性错误的地方,请指出,谢谢。

举报
Mr_Kail
发帖于2年前 0回/230阅
顶部