mirror of https://github.com/apache/cloudstack.git
CS-12510: Deleting the host_details and inserting them back causes deadlocks.
Reviewed-By: Alex Changes: - Deleting and inserting the host_details in one transaction leads to this MySQL deadlock issue sometimes - This fix is to use the ON DUPLICATE KEY UPDATE MySQL query that will insert the deatils if they are new or update the ones that are existing. - This needs a UNIQUE constraint on host_details.
This commit is contained in:
parent
721a85f1b5
commit
c55489224b
|
|
@ -12,6 +12,8 @@
|
|||
// Automatically generated by addcopyright.py at 04/03/2012
|
||||
package com.cloud.host.dao;
|
||||
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.SQLException;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
|
@ -24,6 +26,7 @@ import com.cloud.utils.db.GenericDaoBase;
|
|||
import com.cloud.utils.db.SearchBuilder;
|
||||
import com.cloud.utils.db.SearchCriteria;
|
||||
import com.cloud.utils.db.Transaction;
|
||||
import com.cloud.utils.exception.CloudRuntimeException;
|
||||
|
||||
@Local(value=HostDetailsDao.class)
|
||||
public class HostDetailsDaoImpl extends GenericDaoBase<DetailVO, Long> implements HostDetailsDao {
|
||||
|
|
@ -84,19 +87,26 @@ public class HostDetailsDaoImpl extends GenericDaoBase<DetailVO, Long> implement
|
|||
|
||||
@Override
|
||||
public void persist(long hostId, Map<String, String> details) {
|
||||
final String InsertOrUpdateSql = "INSERT INTO `cloud`.`host_details` (host_id, name, value) VALUES (?,?,?) ON DUPLICATE KEY UPDATE value=?";
|
||||
|
||||
Transaction txn = Transaction.currentTxn();
|
||||
txn.start();
|
||||
SearchCriteria<DetailVO> sc = HostSearch.create();
|
||||
sc.setParameters("hostId", hostId);
|
||||
expunge(sc);
|
||||
|
||||
for (Map.Entry<String, String> detail : details.entrySet()) {
|
||||
String value = detail.getValue();
|
||||
if("password".equals(detail.getKey())){
|
||||
value = DBEncryptionUtil.encrypt(value);
|
||||
}
|
||||
DetailVO vo = new DetailVO(hostId, detail.getKey(), value);
|
||||
persist(vo);
|
||||
String value = detail.getValue();
|
||||
if("password".equals(detail.getKey())){
|
||||
value = DBEncryptionUtil.encrypt(value);
|
||||
}
|
||||
try {
|
||||
PreparedStatement pstmt = txn.prepareAutoCloseStatement(InsertOrUpdateSql);
|
||||
pstmt.setLong(1, hostId);
|
||||
pstmt.setString(2, detail.getKey());
|
||||
pstmt.setString(3, value);
|
||||
pstmt.setString(4, value);
|
||||
pstmt.executeUpdate();
|
||||
} catch (SQLException e) {
|
||||
throw new CloudRuntimeException("Unable to persist the host_details key: "+ detail.getKey() +" for host id: "+hostId, e);
|
||||
}
|
||||
}
|
||||
txn.commit();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -832,7 +832,8 @@ CREATE TABLE `cloud`.`host_details` (
|
|||
`name` varchar(255) NOT NULL,
|
||||
`value` varchar(255) NOT NULL,
|
||||
PRIMARY KEY (`id`),
|
||||
CONSTRAINT `fk_host_details__host_id` FOREIGN KEY (`host_id`) REFERENCES `host`(`id`) ON DELETE CASCADE
|
||||
CONSTRAINT `fk_host_details__host_id` FOREIGN KEY (`host_id`) REFERENCES `host`(`id`) ON DELETE CASCADE,
|
||||
CONSTRAINT UNIQUE KEY (`host_id`, `name`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
|
||||
|
||||
CREATE TABLE `cloud`.`mshost` (
|
||||
|
|
|
|||
|
|
@ -350,3 +350,4 @@ UPDATE `cloud`.`hypervisor_capabilities` SET `max_data_volumes_limit`=13 WHERE `
|
|||
SET SQL_SAFE_UPDATES=1;
|
||||
UPDATE `cloud`.`configuration` SET description='In second, timeout for creating volume from snapshot' WHERE name='create.volume.from.snapshot.wait';
|
||||
|
||||
ALTER TABLE `cloud`.`host_details` ADD CONSTRAINT UNIQUE KEY (`host_id`, `name`);
|
||||
|
|
|
|||
Loading…
Reference in New Issue