如何/何时在我的代码中发生死锁

时间:2014-11-13 09:57:08

标签: java mysql multithreading prepared-statement

我正在使用mysql数据库 我试图找到死锁的原因,但我无法找到它,所以在这里粘贴我的代码。

任何人都可以告诉我how/when this deadlock is coming

下面的代码由5 threads simultaneously执行,但完全在不同的记录上执行(第一个线程正在执行F_Table的前100个,然后另一个线程将执行101到200个F_Table记录,依此类推。)< / p>

String deleteFQuery = "DELETE FROM F_Table WHERE ID IN (?,?,? ...25 times )"; // Deleting old record for given id
String insertFQuery = "INSERT INTO F_Table (columns..) values (?,?..)"; // Reinserting for same id same with updated values
String deleteMpQuery = "DELETE FROM MP_Table WHERE ID IN (?,?,? ...25 times)";
String updateMQuery = "UPDATE M_Table  SET COLUMN1=? WHERE ID IN (?,?,? ...25 times)";

pstmt1 = con.prepareStatement(insertFQuery);
for (i -> 100 times) {
    pstmt1.setString(1, value1); //Values will be set from a list which is getting iterated in this for loop.
    pstmt1.setString(2, value2);
    pstmt1.setString(3, value3);
    pstmt1.setString(4, value4);

    pstmt1.addBatch();

    if ((i1) % 25 == 0) {
        pstmt2 = con.prepareStatement(deleteFuzzyQuery);
        pstmt2.setInt() //this will set 25 values in for loop
        pstmt2.executeUpdate();
        pstmt2.close();

        synchronized (this) {
            pstmt1.executeBatch(); // Deadlock found when trying to get lock; try restarting transaction
                               // Exception : class java.sql.BatchUpdateException
            pstmt1.close();
        }

        pstmt2 = con.prepareStatement(deleteMpQuery);
        pstmt2.setInt() //this will set 25 values in for loop
        pstmt2.executeUpdate();
        pstmt2.close();

        pstmt2 = con.prepareStatement(updateMQuery);
        pstmt2.setInt() //this will set 25 values in for loop
        pstmt2.executeUpdate();
        pstmt2.close();

        con.commit();

        pstmt1 = con.prepareStatement(insertFQuery);
    }
}

注意:死锁将在10次左右发生一次。

感谢。

更新

执行SHOW ENGINE INNODB STATUS后,我在下面找到了日志内容。我真的很新读这个。任何人都可以帮我找到它有什么样的锁。

LATEST DETECTED DEADLOCK
------------------------
2014-11-13 13:13:42 1070
*** (1) TRANSACTION:
TRANSACTION 8871318, ACTIVE 0 sec inserting
mysql tables in use 1, locked 1
LOCK WAIT 3 lock struct(s), heap size 312, 2 row lock(s)
MySQL thread id 7761, OS thread handle 0x1360, query id 145308 dbuser update
INSERT INTO F_TABLE(ID, ...) VALUES ('1',...)
*** (1) WAITING FOR THIS LOCK TO BE GRANTED:
RECORD LOCKS space id 28831 page no 3 n bits 72 index `PRIMARY` of table `dbname`
.`f_table` trx id 8871318 lock_mode X insert intention waiting
Record lock, heap no 1 PHYSICAL RECORD: n_fields 1; compact format; info bits 0
 0: len 8; hex 73757072656d756d; asc supremum;;

*** (2) TRANSACTION:
TRANSACTION 8871319, ACTIVE 0 sec inserting
mysql tables in use 1, locked 1
3 lock struct(s), heap size 312, 2 row lock(s)
MySQL thread id 7763, OS thread handle 0x1070, query id 145309 dbuser update
INSERT INTO F_TABLE(ID, ...) VALUES ('101',...)
*** (2) HOLDS THE LOCK(S):
RECORD LOCKS space id 28831 page no 3 n bits 72 index `PRIMARY` of table `dbname`
.`f_table` trx id 8871319 lock_mode X
Record lock, heap no 1 PHYSICAL RECORD: n_fields 1; compact format; info bits 0
 0: len 8; hex 73757072656d756d; asc supremum;;

*** (2) WAITING FOR THIS LOCK TO BE GRANTED:
RECORD LOCKS space id 28831 page no 3 n bits 72 index `PRIMARY` of table `dbname`
.`f_table` trx id 8871319 lock_mode X insert intention waiting
Record lock, heap no 1 PHYSICAL RECORD: n_fields 1; compact format; info bits 0
 0: len 8; hex 73757072656d756d; asc supremum;;

*** WE ROLL BACK TRANSACTION (2)

更新2:

Added synchronized block。这有助于在执行pstmt1.executeBatch();时避免死锁吗?

1 个答案:

答案 0 :(得分:1)

在mysql中运行SHOW ENGINE INNODB STATUS(如果您的数据库引擎是innodb)。您将获得详细信息 最后检测到的死锁详细信息的引擎状态。您将看到哪个查询处于死锁状态。现在能够从show engine查询中回答您的问题结果会有所帮助。