Merge pull request #144 from bsinno/fix_rolloutmanagement_transaction_handling_deadlock

change transaction handling of creating groups and check running Rollouts
This commit is contained in:
Michael Hirsch
2016-04-28 12:30:52 +02:00
2 changed files with 19 additions and 14 deletions

View File

@@ -58,6 +58,8 @@ import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.stereotype.Service;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.TransactionDefinition;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.support.DefaultTransactionDefinition;
import org.springframework.transaction.support.TransactionTemplate;
@@ -259,13 +261,7 @@ public class RolloutManagement {
entityManager.flush();
executor.execute(() -> {
try {
final DefaultTransactionDefinition def = new DefaultTransactionDefinition();
def.setName("creatingRollout");
def.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRES_NEW);
new TransactionTemplate(txManager, def).execute(status -> {
createRolloutGroups(amountGroup, conditions, savedRollout);
return null;
});
createRolloutGroupsInNewTransaction(amountGroup, conditions, savedRollout);
} finally {
creatingRollouts.remove(savedRollout.getName());
}
@@ -288,13 +284,22 @@ public class RolloutManagement {
}
}
private Rollout createRolloutGroupsInNewTransaction(final int amountOfGroups, final RolloutGroupConditions conditions,
final Rollout savedRollout) {
final DefaultTransactionDefinition def = new DefaultTransactionDefinition();
def.setName("creatingRollout");
def.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRES_NEW);
return new TransactionTemplate(txManager, def)
.execute(status -> createRolloutGroups(amountOfGroups, conditions, savedRollout));
}
/**
* Method for creating rollout groups and calculating group sizes. Group
* sizes are calculated by dividing the total count of targets through the
* amount of given groups. In same cases this will lead to less rollout
* groups than given by client.
*
* @param amountGroup
* @param amountOfGroups
* the amount of groups
* @param conditions
* the rollout group conditions
@@ -302,17 +307,17 @@ public class RolloutManagement {
* the rollout
* @return the rollout with created groups
*/
private Rollout createRolloutGroups(final int amountGroup, final RolloutGroupConditions conditions,
private Rollout createRolloutGroups(final int amountOfGroups, final RolloutGroupConditions conditions,
final Rollout savedRollout) {
int pageIndex = 0;
int groupIndex = 0;
final Long totalCount = savedRollout.getTotalTargets();
final int groupSize = (int) Math.ceil((double) totalCount / (double) amountGroup);
final int groupSize = (int) Math.ceil((double) totalCount / (double) amountOfGroups);
// validate if the amount of groups that will be created are the amount
// of groups that the client what's to have created.
int amountGroupValidated = amountGroup;
int amountGroupValidated = amountOfGroups;
final int amountGroupCreation = (int) (Math.ceil((double) totalCount / (double) groupSize));
if (amountGroupCreation == (amountGroup - 1)) {
if (amountGroupCreation == (amountOfGroups - 1)) {
amountGroupValidated--;
}
RolloutGroup lastSavedGroup = null;
@@ -540,7 +545,7 @@ public class RolloutManagement {
* this check. This check is only applied if the last check is
* less than (lastcheck-delay).
*/
@Transactional
@Transactional(propagation = Propagation.REQUIRES_NEW, isolation = Isolation.READ_UNCOMMITTED)
@Modifying
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_ROLLOUT_MANAGEMENT_WRITE + SpringEvalExpressions.HAS_AUTH_OR
+ SpringEvalExpressions.IS_SYSTEM_CODE)

View File

@@ -164,7 +164,7 @@ public class SystemManagement {
* @return the {@link CurrentTenantKeyGenerator}
*/
@Bean
@Transactional(propagation = Propagation.NOT_SUPPORTED)
@Transactional(propagation = Propagation.SUPPORTS)
public CurrentTenantKeyGenerator currentTenantKeyGenerator() {
return new CurrentTenantKeyGenerator();
}