Mysql
 sql >> база данни >  >> RDS >> Mysql

Как правилно да се справяме с блокирането на InnoDB в Java/JDBC?

Вашият код по същество е правилен. Изключението, което се появява, когато възникне мъртво заключване, е SQLException . Изключението getSQLState() метод предоставя връща код за грешка, който предоставя допълнителна информация относно действителната грешка.

Трябва също така да изчакате малко време между опитите, за да не натоварвате сървъра си твърде много.

Както умело предположихте, задайте максимален брой опити или може да се окажете в безкраен цикъл.

Крайният код може да изглежда така:

boolean oops;
int retries = 5;
Connection c = null;
Statement s = null;
ResultSet rs = null;    

do
{
    oops = false;
    c = null;
    s = null;
    rs = null;
    try
    {
        c = openConnection();
        s = c.createStatement();
        rs = s.executeQuery("SELECT stuff FROM mytable");
        fiddleWith(rs);
    }
    catch (SQLException sqlex)
    {
        oops = true;
        switch(sqlex.getErrorCode()())
        {
            case MysqlErrorNumbers.ER_LOCK_DEADLOCK:
                // deadlock or lock-wait time-out occured
                break;
            ...
        }
        Thread.sleep(1000); // short delay before retry
    }
    finally
    {
        if (rs != null) try {
            rs.close();
        } catch (SQLException e) {
            // some error handler here
        }

        if (s != null) try {
            s.close();
        } catch (SQLException e) {
            // some error handler here
        }

        if (c != null) try {
            c.close();
        } catch (SQLException e) {
            // some error handler here
        }

    }
}
while (oops == true && retries-- > 0);

Очевидно горният код е под оптимален. Може да искате да разграничите грешките, възникващи по време на свързване, и грешките по време на изпълнение. Можете също да откриете, че след някои грешки има малка надежда, че друг опит ще работи (напр. грешни идентификационни данни или грешка в синтаксиса на SQL).

Зададохте много въпроси, но ще се опитам да отговоря на всички:

Да, вижте по-горе:SQLException 's са тези, с повече информация, предоставена от getErrorCode() или getSQLState() .

SQLException може да бъде изхвърлен от почти всички методи на всички класове от java.sql пакет.

Да, вижте по-горе.

Очевидно не трябва да създавате повторно PreparedStatement между две заявки. Просто трябва да зададете нови стойности на вашите параметри, преди да извикате executeQuery() отново. Разбира се, ако трябва да изпълните друга заявка, тогава нов PreparedStatement се изисква.

A (нов) ResultSet обектът се връща от Statement.executeQuery() , което представлява резултата от заявката. Никога не създавате такъв обект сами. В идеалния случай ще извикате ResultSet.close() възможно най-скоро, за да освободите паметта.

Силно ви съветвам да следвате втората глава от този урок („Обработка на SQL изявления“).




  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Задайте изрично типа данни на клетка като текст за числови стойности

  2. Запазена дума в името на колоната - вмъкнете в MySQL

  3. Изберете всички месеци в рамките на даден период от време, включително тези със стойности 0

  4. Как да попречите на Mysql Connector/J да преобразува ДАТА и ЧАСОВА часова зона?

  5. премахване на дублиращи се редове въз основа на стойност на една колона