我正在使用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();
时避免死锁吗?
答案 0 :(得分:1)
在mysql中运行SHOW ENGINE INNODB STATUS
(如果您的数据库引擎是innodb)。您将获得详细信息
最后检测到的死锁详细信息的引擎状态。您将看到哪个查询处于死锁状态。现在能够从show engine查询中回答您的问题结果会有所帮助。