以下情况会导致死锁,如SHOW INNODB STATUS结果所示:
两个事务中没有一个实际上拥有正确的记录,因此我们无法真正理解为什么这会导致死锁,除非存在拥有该锁并且也死锁的第三笔事务。如何对此问题进行进一步调查,并以某种方式将其与触发因素联系起来?
LATEST DETECTED DEADLOCK
------------------------
2018-07-28 08:27:08 0x7f1a08537700
*** (1) TRANSACTION:
TRANSACTION 2183, ACTIVE 0 sec starting index read
mysql tables in use 5, locked 5
LOCK WAIT 7 lock struct(s), heap size 1136, 3 row lock(s), undo log entries 1
MySQL thread id 47, OS thread handle 139750051079936, query id 1481 172.24.0.1 myuser updating
update `mytable` set `status` = 'OK' where `mytable`.`id` = 5
*** (1) WAITING FOR THIS LOCK TO BE GRANTED:
RECORD LOCKS space id 37 page no 3 n bits 72 index PRIMARY of table `mydb`.`mytable` trx id 2183 lock_mode X locks rec but not gap waiting
Record lock, heap no 3 PHYSICAL RECORD: n_fields 18; compact format; info bits 0
0: len 4; hex 80000005; asc ;;
1: len 6; hex 000000000885; asc ;;
2: len 7; hex 2c0000018b0110; asc , ;;
3: len 30; hex 66643164396162382d663462642d343237652d626461362d316430626634; asc fd1d9ab8-f4bd-427e-bda6-1d0bf4; (total 36 bytes);
4: len 4; hex 5b5c28d7; asc [\( ;;
5: len 4; hex 5b5c28dc; asc [\( ;;
6: len 6; hex 80000186a000; asc ;;
7: len 4; hex 80000005; asc ;;
8: len 3; hex 455552; asc EUR;;
9: len 4; hex 80000001; asc ;;
10: len 17; hex 52454144595f464f525f414456414e4345; asc OK;;
11: SQL NULL;
12: len 3; hex 8fc55a; asc Z;;
13: len 3; hex 8fc55a; asc Z;;
14: SQL NULL;
15: len 15; hex 30303141307965644562686c466966; asc 001A0yedEbhlFif;;
16: SQL NULL;
17: len 1; hex 80; asc ;;
*** (2) TRANSACTION:
TRANSACTION 2187, ACTIVE 0 sec starting index read
mysql tables in use 5, locked 5
7 lock struct(s), heap size 1136, 3 row lock(s), undo log entries 1
MySQL thread id 50, OS thread handle OK, query id 1482 172.24.0.1 myuser updating
update `mytable` set `status` = 'OK' where `mytable`.`id` = 5
*** (2) HOLDS THE LOCK(S):
RECORD LOCKS space id 37 page no 3 n bits 72 index PRIMARY of table `mydb`.`mytable` trx id 2187 lock mode S locks rec but not gap
Record lock, heap no 3 PHYSICAL RECORD: n_fields 18; compact format; info bits 0
0: len 4; hex 80000005; asc ;;
1: len 6; hex 000000000885; asc ;;
2: len 7; hex 2c0000018b0110; asc , ;;
3: len 30; hex 66643164396162382d663462642d343237652d626461362d316430626634; asc fd1d9ab8-f4bd-427e-bda6-1d0bf4; (total 36 bytes);
4: len 4; hex 5b5c28d7; asc [\( ;;
5: len 4; hex 5b5c28dc; asc [\( ;;
6: len 6; hex 80000186a000; asc ;;
7: len 4; hex 80000005; asc ;;
8: len 3; hex 455552; asc EUR;;
9: len 4; hex 80000001; asc ;;
10: len 17; hex 52454144595f464f525f414456414e4345; asc OK;;
11: SQL NULL;
12: len 3; hex 8fc55a; asc Z;;
13: len 3; hex 8fc55a; asc Z;;
14: SQL NULL;
15: len 15; hex 30303141307965644562686c466966; asc 001A0yedEbhlFif;;
16: SQL NULL;
17: len 1; hex 80; asc ;;
*** (2) WAITING FOR THIS LOCK TO BE GRANTED:
RECORD LOCKS space id 37 page no 3 n bits 72 index PRIMARY of table `mydb`.`mytable` trx id 2187 lock_mode X locks rec but not gap waiting
Record lock, heap no 3 PHYSICAL RECORD: n_fields 18; compact format; info bits 0
0: len 4; hex 80000005; asc ;;
1: len 6; hex 000000000885; asc ;;
2: len 7; hex 2c0000018b0110; asc , ;;
3: len 30; hex 66643164396162382d663462642d343237652d626461362d316430626634; asc fd1d9ab8-f4bd-427e-bda6-1d0bf4; (total 36 bytes);
4: len 4; hex 5b5c28d7; asc [\( ;;
5: len 4; hex 5b5c28dc; asc [\( ;;
6: len 6; hex 80000186a000; asc ;;
7: len 4; hex 80000005; asc ;;
8: len 3; hex 455552; asc EUR;;
9: len 4; hex 80000001; asc ;;
10: len 17; hex 52454144595f464f525f414456414e4345; asc OK;;
11: SQL NULL;
12: len 3; hex 8fc55a; asc Z;;
13: len 3; hex 8fc55a; asc Z;;
14: SQL NULL;
15: len 15; hex 30303141307965644562686c466966; asc 001A0yedEbhlFif;;
16: SQL NULL;
17: len 1; hex 80; asc ;;
*** WE ROLL BACK TRANSACTION (2)
答案 0 :(得分:0)
第二个事务确实拥有共享(public class SQLTableImport {
//***********Constructor for Filter Table export (2 columns Check box and string)**********
public SQLTableImport(String descriptionColumn){
if(getSqlSelectedType().equals("BLOB")){
setSql("SELECT DISTINCT "+getSqlColumnName()+" , "+descriptionColumn+" FROM `"+ getTableName() +"`"+whereClause+"");
}
else{
setSql("SELECT DISTINCT "+getSqlColumnName()+" FROM `"+ getTableName() +"`"+whereClause+"");
}
}
//***********METHOD FOR RETURNING THE MODEL FOR A FILTER FRAME 1 COLUMN AND 1 CHECKBOX COLUMN
public DefaultTableModel getFilterModelFromSqlTable(){
if(getSqlSelectedType().equals("BLOB")){emptyHeaders= new Object[][]{null,null,null};}
DefaultTableModel dFilterTableModel = new DefaultTableModel(emptyrows, emptyHeaders){
private static final long serialVersionUID = 1L;
@Override
public boolean isCellEditable(int row, int column) {
return column == 0;
}
public Class <?> getColumnClass(int column) {
if(column==0){
return Boolean.class;
}
if(column==2){
return String.class;
}
switch (getSqlColumnType()[CustomTable.getColumnIndex()]) {
case "VARCHAR":
return String.class;
case "INT":
return Integer.class;
case "DECIMAL":
return Double.class;
case "DATE":
return Date.class;
case "TINYINT":
return String.class;
case "BLOB":
return Icon.class;
default:
return Object.class;
}
}
};
try {
setPst(Utilities.sqlConnnect().prepareStatement(getSql()));
setRs(getPst().executeQuery(getSql()));
java.sql.ResultSetMetaData tempResult = getPst().getMetaData();
int tempColumnCount = tempResult.getColumnCount();
Object[] tempRow= new Object[tempColumnCount+1];
while(getRs().next()){
// Gets the column values based on class type expected
tempRow[0]= false;
if(getSqlColumnType()[CustomTable.getColumnIndex()].equals("VARCHAR")){
tempRow[tempColumnCount]= getRs().getString(tempColumnCount);
}
if(getSqlColumnType()[CustomTable.getColumnIndex()].equals("INT")){
tempRow[tempColumnCount]= getRs().getInt(tempColumnCount);
}
if(getSqlColumnType()[CustomTable.getColumnIndex()].equals("DECIMAL")){
tempRow[tempColumnCount]= getRs().getDouble(tempColumnCount);
}
if(getSqlColumnType()[CustomTable.getColumnIndex()].toString().equals("DATE")){
}
if(getSqlColumnType()[CustomTable.getColumnIndex()].equals("TINYINT")){
tempRow[tempColumnCount]= getRs().getBoolean(tempColumnCount);
}
if(getSqlColumnType()[CustomTable.getColumnIndex()].equals("BLOB")){
Blob blob = getRs().getBlob(tempColumnCount-1);
ImageIcon icon = null;
try (InputStream is = blob.getBinaryStream()) {
BufferedImage img = ImageIO.read(is);
icon = new ImageIcon(img.getScaledInstance(17, 17, Image.SCALE_SMOOTH));
}
tempRow[tempColumnCount-1] =icon;
tempRow[tempColumnCount]= getRs().getString(tempColumnCount);
}
// Adds the row of data to the end of the model
dFilterTableModel.addRow(tempRow);
}
} catch (Exception e) {
JOptionPane.showMessageDialog(null,e);
}
finally {
try {
getPst().close();
getRs().close();
} catch (SQLException e1) {
JOptionPane.showMessageDialog(null,e1);
}
}
return dFilterTableModel;}
)锁,这防止了第一个事务获得独占(S
)锁。
但是mysql注册了第一个事务想要一个排他锁,该锁进入了队列。
然后第二个事务想要将锁升级为独占锁,这是不可以的,因为第一笔事务已经注册了其独占锁的意图。
这是mysql中死锁的教科书案例,请参见mysql手册中的14.5.5.1 An InnoDB Deadlock Example部分