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

View File

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