killbill-memoizeit

dao: inject read-only DBI Not yet in use. Signed-off-by:

3/9/2018 7:52:33 AM

Changes

Details

diff --git a/account/src/main/java/org/killbill/billing/account/api/svcs/DefaultImmutableAccountInternalApi.java b/account/src/main/java/org/killbill/billing/account/api/svcs/DefaultImmutableAccountInternalApi.java
index 4bdf0c6..5d179be 100644
--- a/account/src/main/java/org/killbill/billing/account/api/svcs/DefaultImmutableAccountInternalApi.java
+++ b/account/src/main/java/org/killbill/billing/account/api/svcs/DefaultImmutableAccountInternalApi.java
@@ -1,6 +1,6 @@
 /*
- * Copyright 2016-2017 Groupon, Inc
- * Copyright 2016-2017 The Billing Project, LLC
+ * Copyright 2014-2018 Groupon, Inc
+ * Copyright 2014-2018 The Billing Project, LLC
  *
  * The Billing Project licenses this file to you under the Apache License, version 2.0
  * (the "License"); you may not use this file except in compliance with the
@@ -19,6 +19,8 @@ package org.killbill.billing.account.api.svcs;
 
 import java.util.UUID;
 
+import javax.inject.Named;
+
 import org.killbill.billing.ObjectType;
 import org.killbill.billing.account.api.Account;
 import org.killbill.billing.account.api.AccountApiException;
@@ -44,6 +46,8 @@ import org.skife.jdbi.v2.IDBI;
 
 import com.google.inject.Inject;
 
+import static org.killbill.billing.util.glue.IDBISetup.MAIN_RO_IDBI_NAMED;
+
 public class DefaultImmutableAccountInternalApi implements ImmutableAccountInternalApi {
 
     private final EntitySqlDaoTransactionalJdbiWrapper transactionalSqlDao;
@@ -53,11 +57,12 @@ public class DefaultImmutableAccountInternalApi implements ImmutableAccountInter
 
     @Inject
     public DefaultImmutableAccountInternalApi(final IDBI dbi,
+                                              @Named(MAIN_RO_IDBI_NAMED) final IDBI roDbi,
                                               final Clock clock,
                                               final NonEntityDao nonEntityDao,
                                               final CacheControllerDispatcher cacheControllerDispatcher) {
         // This API will directly issue queries instead of relying on the DAO (introduced to avoid Guice circular dependencies with InternalCallContextFactory)
-        this.transactionalSqlDao = new EntitySqlDaoTransactionalJdbiWrapper(dbi, clock, cacheControllerDispatcher, nonEntityDao, null);
+        this.transactionalSqlDao = new EntitySqlDaoTransactionalJdbiWrapper(dbi, roDbi, clock, cacheControllerDispatcher, nonEntityDao, null);
         this.nonEntityDao = nonEntityDao;
         this.accountCacheController = cacheControllerDispatcher.getCacheController(CacheType.ACCOUNT_IMMUTABLE);
         this.recordIdCacheController = cacheControllerDispatcher.getCacheController(CacheType.RECORD_ID);
diff --git a/account/src/main/java/org/killbill/billing/account/dao/DefaultAccountDao.java b/account/src/main/java/org/killbill/billing/account/dao/DefaultAccountDao.java
index 919ccf3..4ac4a10 100644
--- a/account/src/main/java/org/killbill/billing/account/dao/DefaultAccountDao.java
+++ b/account/src/main/java/org/killbill/billing/account/dao/DefaultAccountDao.java
@@ -1,7 +1,7 @@
 /*
  * Copyright 2010-2013 Ning, Inc.
- * Copyright 2014-2017 Groupon, Inc
- * Copyright 2014-2017 The Billing Project, LLC
+ * Copyright 2014-2018 Groupon, Inc
+ * Copyright 2014-2018 The Billing Project, LLC
  *
  * The Billing Project licenses this file to you under the Apache License, version 2.0
  * (the "License"); you may not use this file except in compliance with the
@@ -22,6 +22,8 @@ import java.util.Iterator;
 import java.util.List;
 import java.util.UUID;
 
+import javax.inject.Named;
+
 import org.killbill.billing.BillingExceptionBase;
 import org.killbill.billing.ErrorCode;
 import org.killbill.billing.account.api.Account;
@@ -57,10 +59,11 @@ import org.skife.jdbi.v2.IDBI;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import com.google.common.base.Preconditions;
 import com.google.common.collect.ImmutableList;
 import com.google.inject.Inject;
 
+import static org.killbill.billing.util.glue.IDBISetup.MAIN_RO_IDBI_NAMED;
+
 public class DefaultAccountDao extends EntityDaoBase<AccountModelDao, Account, AccountApiException> implements AccountDao {
 
     private static final Logger log = LoggerFactory.getLogger(DefaultAccountDao.class);
@@ -71,10 +74,10 @@ public class DefaultAccountDao extends EntityDaoBase<AccountModelDao, Account, A
     private final Clock clock;
 
     @Inject
-    public DefaultAccountDao(final IDBI dbi, final PersistentBus eventBus, final Clock clock, final CacheControllerDispatcher cacheControllerDispatcher,
+    public DefaultAccountDao(final IDBI dbi, @Named(MAIN_RO_IDBI_NAMED) final IDBI roDbi, final PersistentBus eventBus, final Clock clock, final CacheControllerDispatcher cacheControllerDispatcher,
                              final InternalCallContextFactory internalCallContextFactory, final NonEntityDao nonEntityDao) {
-        super(new EntitySqlDaoTransactionalJdbiWrapper(dbi, clock, cacheControllerDispatcher, nonEntityDao, internalCallContextFactory), AccountSqlDao.class);
-        this.accountImmutableCacheController  = cacheControllerDispatcher.getCacheController(CacheType.ACCOUNT_IMMUTABLE);
+        super(new EntitySqlDaoTransactionalJdbiWrapper(dbi, roDbi, clock, cacheControllerDispatcher, nonEntityDao, internalCallContextFactory), AccountSqlDao.class);
+        this.accountImmutableCacheController = cacheControllerDispatcher.getCacheController(CacheType.ACCOUNT_IMMUTABLE);
         this.eventBus = eventBus;
         this.internalCallContextFactory = internalCallContextFactory;
         this.clock = clock;
diff --git a/entitlement/src/main/java/org/killbill/billing/entitlement/dao/DefaultBlockingStateDao.java b/entitlement/src/main/java/org/killbill/billing/entitlement/dao/DefaultBlockingStateDao.java
index 29c193c..2ec8ff9 100644
--- a/entitlement/src/main/java/org/killbill/billing/entitlement/dao/DefaultBlockingStateDao.java
+++ b/entitlement/src/main/java/org/killbill/billing/entitlement/dao/DefaultBlockingStateDao.java
@@ -1,7 +1,7 @@
 /*
  * Copyright 2010-2013 Ning, Inc.
- * Copyright 2014-2017 Groupon, Inc
- * Copyright 2014-2017 The Billing Project, LLC
+ * Copyright 2014-2018 Groupon, Inc
+ * Copyright 2014-2018 The Billing Project, LLC
  *
  * The Billing Project licenses this file to you under the Apache License, version 2.0
  * (the "License"); you may not use this file except in compliance with the
@@ -29,6 +29,7 @@ import java.util.Map;
 import java.util.UUID;
 
 import javax.annotation.Nullable;
+import javax.inject.Named;
 
 import org.joda.time.DateTime;
 import org.killbill.billing.ErrorCode;
@@ -73,6 +74,8 @@ import com.google.common.collect.Collections2;
 import com.google.common.collect.ImmutableList;
 import com.google.common.collect.Ordering;
 
+import static org.killbill.billing.util.glue.IDBISetup.MAIN_RO_IDBI_NAMED;
+
 public class DefaultBlockingStateDao extends EntityDaoBase<BlockingStateModelDao, BlockingState, EntitlementApiException> implements BlockingStateDao {
 
     private static final Logger log = LoggerFactory.getLogger(DefaultBlockingStateDao.class);
@@ -112,9 +115,9 @@ public class DefaultBlockingStateDao extends EntityDaoBase<BlockingStateModelDao
 
     private final StatelessBlockingChecker statelessBlockingChecker = new StatelessBlockingChecker();
 
-    public DefaultBlockingStateDao(final IDBI dbi, final Clock clock, final NotificationQueueService notificationQueueService, final PersistentBus eventBus,
+    public DefaultBlockingStateDao(final IDBI dbi, @Named(MAIN_RO_IDBI_NAMED) final IDBI roDbi, final Clock clock, final NotificationQueueService notificationQueueService, final PersistentBus eventBus,
                                    final CacheControllerDispatcher cacheControllerDispatcher, final NonEntityDao nonEntityDao, final InternalCallContextFactory internalCallContextFactory) {
-        super(new EntitySqlDaoTransactionalJdbiWrapper(dbi, clock, cacheControllerDispatcher, nonEntityDao, internalCallContextFactory), BlockingStateSqlDao.class);
+        super(new EntitySqlDaoTransactionalJdbiWrapper(dbi, roDbi, clock, cacheControllerDispatcher, nonEntityDao, internalCallContextFactory), BlockingStateSqlDao.class);
         this.clock = clock;
         this.notificationQueueService = notificationQueueService;
         this.eventBus = eventBus;
diff --git a/entitlement/src/main/java/org/killbill/billing/entitlement/dao/OptimizedProxyBlockingStateDao.java b/entitlement/src/main/java/org/killbill/billing/entitlement/dao/OptimizedProxyBlockingStateDao.java
index 35c718a..eb415a0 100644
--- a/entitlement/src/main/java/org/killbill/billing/entitlement/dao/OptimizedProxyBlockingStateDao.java
+++ b/entitlement/src/main/java/org/killbill/billing/entitlement/dao/OptimizedProxyBlockingStateDao.java
@@ -1,7 +1,7 @@
 /*
  * Copyright 2010-2013 Ning, Inc.
- * Copyright 2014-2016 Groupon, Inc
- * Copyright 2014-2016 The Billing Project, LLC
+ * Copyright 2014-2018 Groupon, Inc
+ * Copyright 2014-2018 The Billing Project, LLC
  *
  * The Billing Project licenses this file to you under the Apache License, version 2.0
  * (the "License"); you may not use this file except in compliance with the
@@ -47,9 +47,9 @@ import com.google.common.collect.ImmutableList;
 public class OptimizedProxyBlockingStateDao extends ProxyBlockingStateDao {
 
     public OptimizedProxyBlockingStateDao(final EventsStreamBuilder eventsStreamBuilder, final SubscriptionBaseInternalApi subscriptionBaseInternalApi,
-                                          final IDBI dbi, final Clock clock, final NotificationQueueService notificationQueueService, final PersistentBus eventBus,
+                                          final IDBI dbi, final IDBI roDbi, final Clock clock, final NotificationQueueService notificationQueueService, final PersistentBus eventBus,
                                           final CacheControllerDispatcher cacheControllerDispatcher, final NonEntityDao nonEntityDao, final InternalCallContextFactory internalCallContextFactory) {
-        super(eventsStreamBuilder, subscriptionBaseInternalApi, dbi, clock, notificationQueueService, eventBus, cacheControllerDispatcher, nonEntityDao, internalCallContextFactory);
+        super(eventsStreamBuilder, subscriptionBaseInternalApi, dbi, roDbi, clock, notificationQueueService, eventBus, cacheControllerDispatcher, nonEntityDao, internalCallContextFactory);
     }
 
     /**
diff --git a/entitlement/src/main/java/org/killbill/billing/entitlement/dao/ProxyBlockingStateDao.java b/entitlement/src/main/java/org/killbill/billing/entitlement/dao/ProxyBlockingStateDao.java
index ea237a3..ad5c151 100644
--- a/entitlement/src/main/java/org/killbill/billing/entitlement/dao/ProxyBlockingStateDao.java
+++ b/entitlement/src/main/java/org/killbill/billing/entitlement/dao/ProxyBlockingStateDao.java
@@ -1,7 +1,7 @@
 /*
  * Copyright 2010-2013 Ning, Inc.
- * Copyright 2014-2016 Groupon, Inc
- * Copyright 2014-2016 The Billing Project, LLC
+ * Copyright 2014-2018 Groupon, Inc
+ * Copyright 2014-2018 The Billing Project, LLC
  *
  * The Billing Project licenses this file to you under the Apache License, version 2.0
  * (the "License"); you may not use this file except in compliance with the
@@ -27,6 +27,7 @@ import java.util.UUID;
 
 import javax.annotation.Nullable;
 import javax.inject.Inject;
+import javax.inject.Named;
 import javax.inject.Singleton;
 
 import org.joda.time.DateTime;
@@ -60,6 +61,8 @@ import com.google.common.base.Predicate;
 import com.google.common.collect.Iterables;
 import com.google.common.collect.Ordering;
 
+import static org.killbill.billing.util.glue.IDBISetup.MAIN_RO_IDBI_NAMED;
+
 @Singleton
 public class ProxyBlockingStateDao implements BlockingStateDao {
 
@@ -171,12 +174,12 @@ public class ProxyBlockingStateDao implements BlockingStateDao {
 
     @Inject
     public ProxyBlockingStateDao(final EventsStreamBuilder eventsStreamBuilder, final SubscriptionBaseInternalApi subscriptionBaseInternalApi,
-                                 final IDBI dbi, final Clock clock, final NotificationQueueService notificationQueueService, final PersistentBus eventBus,
+                                 final IDBI dbi, @Named(MAIN_RO_IDBI_NAMED) final IDBI roDbi, final Clock clock, final NotificationQueueService notificationQueueService, final PersistentBus eventBus,
                                  final CacheControllerDispatcher cacheControllerDispatcher, final NonEntityDao nonEntityDao, final InternalCallContextFactory internalCallContextFactory) {
         this.eventsStreamBuilder = eventsStreamBuilder;
         this.subscriptionInternalApi = subscriptionBaseInternalApi;
         this.clock = clock;
-        this.delegate = new DefaultBlockingStateDao(dbi, clock, notificationQueueService, eventBus, cacheControllerDispatcher, nonEntityDao, internalCallContextFactory);
+        this.delegate = new DefaultBlockingStateDao(dbi, roDbi, clock, notificationQueueService, eventBus, cacheControllerDispatcher, nonEntityDao, internalCallContextFactory);
     }
 
     @Override
diff --git a/entitlement/src/main/java/org/killbill/billing/entitlement/engine/core/EventsStreamBuilder.java b/entitlement/src/main/java/org/killbill/billing/entitlement/engine/core/EventsStreamBuilder.java
index b2b436a..ef40ca5 100644
--- a/entitlement/src/main/java/org/killbill/billing/entitlement/engine/core/EventsStreamBuilder.java
+++ b/entitlement/src/main/java/org/killbill/billing/entitlement/engine/core/EventsStreamBuilder.java
@@ -1,7 +1,7 @@
 /*
  * Copyright 2010-2013 Ning, Inc.
- * Copyright 2014-2016 Groupon, Inc
- * Copyright 2014-2016 The Billing Project, LLC
+ * Copyright 2014-2018 Groupon, Inc
+ * Copyright 2014-2018 The Billing Project, LLC
  *
  * The Billing Project licenses this file to you under the Apache License, version 2.0
  * (the "License"); you may not use this file except in compliance with the
@@ -28,6 +28,7 @@ import java.util.UUID;
 
 import javax.annotation.Nullable;
 import javax.inject.Inject;
+import javax.inject.Named;
 import javax.inject.Singleton;
 
 import org.killbill.billing.ObjectType;
@@ -71,6 +72,8 @@ import com.google.common.base.Predicate;
 import com.google.common.collect.ImmutableList;
 import com.google.common.collect.Iterables;
 
+import static org.killbill.billing.util.glue.IDBISetup.MAIN_RO_IDBI_NAMED;
+
 @Singleton
 public class EventsStreamBuilder {
 
@@ -84,7 +87,7 @@ public class EventsStreamBuilder {
 
     @Inject
     public EventsStreamBuilder(final AccountInternalApi accountInternalApi, final SubscriptionBaseInternalApi subscriptionInternalApi,
-                               final BlockingChecker checker, final IDBI dbi, final Clock clock,
+                               final BlockingChecker checker, final IDBI dbi, @Named(MAIN_RO_IDBI_NAMED) final IDBI roDbi, final Clock clock,
                                final NotificationQueueService notificationQueueService, final PersistentBus eventBus,
                                final CacheControllerDispatcher cacheControllerDispatcher,
                                final NonEntityDao nonEntityDao,
@@ -94,8 +97,8 @@ public class EventsStreamBuilder {
         this.checker = checker;
         this.clock = clock;
         this.internalCallContextFactory = internalCallContextFactory;
-        this.defaultBlockingStateDao = new DefaultBlockingStateDao(dbi, clock, notificationQueueService, eventBus, cacheControllerDispatcher, nonEntityDao, internalCallContextFactory);
-        this.blockingStateDao = new OptimizedProxyBlockingStateDao(this, subscriptionInternalApi, dbi, clock, notificationQueueService, eventBus, cacheControllerDispatcher, nonEntityDao, internalCallContextFactory);
+        this.defaultBlockingStateDao = new DefaultBlockingStateDao(dbi, roDbi, clock, notificationQueueService, eventBus, cacheControllerDispatcher, nonEntityDao, internalCallContextFactory);
+        this.blockingStateDao = new OptimizedProxyBlockingStateDao(this, subscriptionInternalApi, dbi, roDbi, clock, notificationQueueService, eventBus, cacheControllerDispatcher, nonEntityDao, internalCallContextFactory);
     }
 
     public EventsStream refresh(final EventsStream eventsStream, final TenantContext tenantContext) throws EntitlementApiException {
@@ -335,7 +338,6 @@ public class EventsStreamBuilder {
                                              final Map<UUID, Integer> bcdCache,
                                              final InternalTenantContext internalTenantContext) throws EntitlementApiException {
 
-
         try {
             int accountBCD = accountInternalApi.getBCD(account.getId(), internalTenantContext);
             int defaultAlignmentDay = subscriptionInternalApi.getDefaultBillCycleDayLocal(bcdCache, subscription, baseSubscription, createPlanPhaseSpecifier(subscription), accountBCD, clock.getUTCNow(), internalTenantContext);
diff --git a/invoice/src/main/java/org/killbill/billing/invoice/dao/DefaultInvoiceDao.java b/invoice/src/main/java/org/killbill/billing/invoice/dao/DefaultInvoiceDao.java
index 8720a38..905b11e 100644
--- a/invoice/src/main/java/org/killbill/billing/invoice/dao/DefaultInvoiceDao.java
+++ b/invoice/src/main/java/org/killbill/billing/invoice/dao/DefaultInvoiceDao.java
@@ -1,7 +1,7 @@
 /*
  * Copyright 2010-2013 Ning, Inc.
- * Copyright 2014-2017 Groupon, Inc
- * Copyright 2014-2017 The Billing Project, LLC
+ * Copyright 2014-2018 Groupon, Inc
+ * Copyright 2014-2018 The Billing Project, LLC
  *
  * The Billing Project licenses this file to you under the Apache License, version 2.0
  * (the "License"); you may not use this file except in compliance with the
@@ -30,6 +30,7 @@ import java.util.Set;
 import java.util.UUID;
 
 import javax.annotation.Nullable;
+import javax.inject.Named;
 
 import org.joda.time.DateTime;
 import org.joda.time.LocalDate;
@@ -86,12 +87,13 @@ import com.google.common.base.Function;
 import com.google.common.base.Preconditions;
 import com.google.common.base.Predicate;
 import com.google.common.collect.ImmutableList;
-import com.google.common.collect.ImmutableMap;
 import com.google.common.collect.ImmutableSet;
 import com.google.common.collect.Iterables;
 import com.google.common.collect.Ordering;
 import com.google.inject.Inject;
 
+import static org.killbill.billing.util.glue.IDBISetup.MAIN_RO_IDBI_NAMED;
+
 public class DefaultInvoiceDao extends EntityDaoBase<InvoiceModelDao, Invoice, InvoiceApiException> implements InvoiceDao {
 
     private static final Logger log = LoggerFactory.getLogger(DefaultInvoiceDao.class);
@@ -126,6 +128,7 @@ public class DefaultInvoiceDao extends EntityDaoBase<InvoiceModelDao, Invoice, I
     @Inject
     public DefaultInvoiceDao(final TagInternalApi tagInternalApi,
                              final IDBI dbi,
+                             @Named(MAIN_RO_IDBI_NAMED) final IDBI roDbi,
                              final NextBillingDatePoster nextBillingDatePoster,
                              final PersistentBus eventBus,
                              final Clock clock,
@@ -136,7 +139,7 @@ public class DefaultInvoiceDao extends EntityDaoBase<InvoiceModelDao, Invoice, I
                              final CBADao cbaDao,
                              final ParentInvoiceCommitmentPoster parentInvoiceCommitmentPoster,
                              final InternalCallContextFactory internalCallContextFactory) {
-        super(new EntitySqlDaoTransactionalJdbiWrapper(dbi, clock, cacheControllerDispatcher, nonEntityDao, internalCallContextFactory), InvoiceSqlDao.class);
+        super(new EntitySqlDaoTransactionalJdbiWrapper(dbi, roDbi, clock, cacheControllerDispatcher, nonEntityDao, internalCallContextFactory), InvoiceSqlDao.class);
         this.tagInternalApi = tagInternalApi;
         this.nextBillingDatePoster = nextBillingDatePoster;
         this.eventBus = eventBus;
@@ -359,7 +362,7 @@ public class DefaultInvoiceDao extends EntityDaoBase<InvoiceModelDao, Invoice, I
                     }
 
                     final boolean wasInvoiceCreatedOrCommitted = createdInvoiceIds.contains(invoiceModelDao.getId()) ||
-                                                       committedReusedInvoiceId.contains(invoiceModelDao.getId());
+                                                                 committedReusedInvoiceId.contains(invoiceModelDao.getId());
                     if (InvoiceStatus.COMMITTED.equals(invoiceModelDao.getStatus())) {
 
                         if (wasInvoiceCreatedOrCommitted) {
@@ -472,7 +475,6 @@ public class DefaultInvoiceDao extends EntityDaoBase<InvoiceModelDao, Invoice, I
                              cur.getParentInvoice().getStatus() == InvoiceStatus.VOID ||
                              InvoiceModelDaoHelper.getRawBalanceForRegularInvoice(cur.getParentInvoice()).compareTo(BigDecimal.ZERO) == 0);
 
-
                     // invoices that are WRITTEN_OFF or paid children invoices are excluded from balance computation but the cba summation needs to be included
                     accountBalance = cur.isWrittenOff() || hasZeroParentBalance ? BigDecimal.ZERO : accountBalance.add(InvoiceModelDaoHelper.getRawBalanceForRegularInvoice(cur));
                     cba = cba.add(InvoiceModelDaoHelper.getCBAAmount(cur));
@@ -539,7 +541,6 @@ public class DefaultInvoiceDao extends EntityDaoBase<InvoiceModelDao, Invoice, I
                                                final Map<UUID, BigDecimal> invoiceItemIdsWithNullAmounts, final String transactionExternalKey,
                                                final InternalCallContext context) throws InvoiceApiException {
 
-
         if (isInvoiceAdjusted && invoiceItemIdsWithNullAmounts.size() == 0) {
             throw new InvoiceApiException(ErrorCode.INVOICE_ITEMS_ADJUSTMENT_MISSING);
         }
@@ -814,7 +815,6 @@ public class DefaultInvoiceDao extends EntityDaoBase<InvoiceModelDao, Invoice, I
         });
     }
 
-
     @Override
     public void notifyOfPaymentInit(final InvoicePaymentModelDao invoicePayment, final InternalCallContext context) {
         notifyOfPaymentCompletionInternal(invoicePayment, false, context);
@@ -1102,7 +1102,7 @@ public class DefaultInvoiceDao extends EntityDaoBase<InvoiceModelDao, Invoice, I
                 // Retrieve the invoice and make sure it belongs to the right account
                 final InvoiceModelDao invoice = transactional.getById(invoiceId.toString(), context);
 
-                if (invoice == null ) {
+                if (invoice == null) {
                     throw new InvoiceApiException(ErrorCode.INVOICE_NOT_FOUND, invoiceId);
                 }
 
@@ -1110,7 +1110,6 @@ public class DefaultInvoiceDao extends EntityDaoBase<InvoiceModelDao, Invoice, I
                     throw new InvoiceApiException(ErrorCode.INVOICE_INVALID_STATUS, newStatus, invoiceId, invoice.getStatus());
                 }
 
-
                 transactional.updateStatus(invoiceId.toString(), newStatus.toString(), context);
 
                 cbaDao.doCBAComplexityFromTransaction(invoicesTags, entitySqlDaoWrapperFactory, context);
@@ -1131,8 +1130,8 @@ public class DefaultInvoiceDao extends EntityDaoBase<InvoiceModelDao, Invoice, I
             final BigDecimal rawBalance = InvoiceModelDaoHelper.getRawBalanceForRegularInvoice(invoice);
             final DefaultInvoiceCreationEvent event = new DefaultInvoiceCreationEvent(invoice.getId(), invoice.getAccountId(),
                                                                                       rawBalance, invoice.getCurrency(),
-                                                                                                            context.getAccountRecordId(), context.getTenantRecordId(),
-                                                                                                            context.getUserToken());
+                                                                                      context.getAccountRecordId(), context.getTenantRecordId(),
+                                                                                      context.getUserToken());
             eventBus.postFromTransaction(event, entitySqlDaoWrapperFactory.getHandle().getConnection());
         } catch (final EventBusException e) {
             log.error(String.format("Failed to post invoice creation event %s for account %s", invoice.getAccountId()), e);
@@ -1203,7 +1202,7 @@ public class DefaultInvoiceDao extends EntityDaoBase<InvoiceModelDao, Invoice, I
                 // Retrieve the invoice and make sure it belongs to the right account
                 final InvoiceItemModelDao invoiceItem = transactional.getById(invoiceItemId.toString(), context);
 
-                if (invoiceItem == null ) {
+                if (invoiceItem == null) {
                     throw new InvoiceApiException(ErrorCode.INVOICE_ITEM_NOT_FOUND, invoiceItemId);
                 }
 
@@ -1243,16 +1242,16 @@ public class DefaultInvoiceDao extends EntityDaoBase<InvoiceModelDao, Invoice, I
                                                                             InvoiceStatus.COMMITTED);
                 final String chargeDescription = "Charge to move credit from child to parent account";
                 final InvoiceItem externalChargeItem = new ExternalChargeInvoiceItem(UUIDs.randomUUID(),
-                                                                                 childCreatedDate,
-                                                                                 invoiceForExternalCharge.getId(),
-                                                                                 childAccount.getId(),
-                                                                                 null,
-                                                                                 chargeDescription,
-                                                                                 childCreatedDate.toLocalDate(),
-                                                                                 childCreatedDate.toLocalDate(),
-                                                                                 accountCBA,
-                                                                                 childAccount.getCurrency(),
-                                                                                 null);
+                                                                                     childCreatedDate,
+                                                                                     invoiceForExternalCharge.getId(),
+                                                                                     childAccount.getId(),
+                                                                                     null,
+                                                                                     chargeDescription,
+                                                                                     childCreatedDate.toLocalDate(),
+                                                                                     childCreatedDate.toLocalDate(),
+                                                                                     accountCBA,
+                                                                                     childAccount.getCurrency(),
+                                                                                     null);
                 invoiceForExternalCharge.addInvoiceItem(externalChargeItem);
 
                 // create credit to parent account
@@ -1274,7 +1273,6 @@ public class DefaultInvoiceDao extends EntityDaoBase<InvoiceModelDao, Invoice, I
                                                                         childAccount.getCurrency());
                 invoiceForCredit.addInvoiceItem(creditItem);
 
-
                 // save invoices and invoice items
                 final InvoiceModelDao childInvoice = new InvoiceModelDao(invoiceForExternalCharge);
                 createAndRefresh(invoiceSqlDao, childInvoice, childAccountContext);
diff --git a/overdue/src/main/java/org/killbill/billing/overdue/notification/DefaultOverduePosterBase.java b/overdue/src/main/java/org/killbill/billing/overdue/notification/DefaultOverduePosterBase.java
index fc14f47..d4805d9 100644
--- a/overdue/src/main/java/org/killbill/billing/overdue/notification/DefaultOverduePosterBase.java
+++ b/overdue/src/main/java/org/killbill/billing/overdue/notification/DefaultOverduePosterBase.java
@@ -21,6 +21,8 @@ package org.killbill.billing.overdue.notification;
 import java.util.Iterator;
 import java.util.UUID;
 
+import javax.inject.Named;
+
 import org.joda.time.DateTime;
 import org.killbill.billing.callcontext.InternalCallContext;
 import org.killbill.billing.overdue.service.DefaultOverdueService;
@@ -41,6 +43,8 @@ import org.slf4j.LoggerFactory;
 
 import com.google.common.annotations.VisibleForTesting;
 
+import static org.killbill.billing.util.glue.IDBISetup.MAIN_RO_IDBI_NAMED;
+
 public abstract class DefaultOverduePosterBase implements OverduePoster {
 
     private static final Logger log = LoggerFactory.getLogger(DefaultOverduePosterBase.class);
@@ -49,10 +53,10 @@ public abstract class DefaultOverduePosterBase implements OverduePoster {
     private final EntitySqlDaoTransactionalJdbiWrapper transactionalSqlDao;
 
     public DefaultOverduePosterBase(final NotificationQueueService notificationQueueService,
-                                    final IDBI dbi, final Clock clock, final CacheControllerDispatcher cacheControllerDispatcher,
+                                    final IDBI dbi, @Named(MAIN_RO_IDBI_NAMED) final IDBI roDbi, final Clock clock, final CacheControllerDispatcher cacheControllerDispatcher,
                                     final NonEntityDao nonEntityDao, final InternalCallContextFactory internalCallContextFactory) {
         this.notificationQueueService = notificationQueueService;
-        this.transactionalSqlDao = new EntitySqlDaoTransactionalJdbiWrapper(dbi, clock, cacheControllerDispatcher, nonEntityDao, internalCallContextFactory);
+        this.transactionalSqlDao = new EntitySqlDaoTransactionalJdbiWrapper(dbi, roDbi, clock, cacheControllerDispatcher, nonEntityDao, internalCallContextFactory);
     }
 
     @Override
diff --git a/overdue/src/main/java/org/killbill/billing/overdue/notification/OverdueAsyncBusPoster.java b/overdue/src/main/java/org/killbill/billing/overdue/notification/OverdueAsyncBusPoster.java
index 9876898..3189c49 100644
--- a/overdue/src/main/java/org/killbill/billing/overdue/notification/OverdueAsyncBusPoster.java
+++ b/overdue/src/main/java/org/killbill/billing/overdue/notification/OverdueAsyncBusPoster.java
@@ -1,7 +1,7 @@
 /*
  * Copyright 2010-2013 Ning, Inc.
- * Copyright 2014-2017 Groupon, Inc
- * Copyright 2014-2017 The Billing Project, LLC
+ * Copyright 2014-2018 Groupon, Inc
+ * Copyright 2014-2018 The Billing Project, LLC
  *
  * The Billing Project licenses this file to you under the Apache License, version 2.0
  * (the "License"); you may not use this file except in compliance with the
@@ -18,6 +18,8 @@
 
 package org.killbill.billing.overdue.notification;
 
+import javax.inject.Named;
+
 import org.joda.time.DateTime;
 import org.killbill.billing.util.cache.CacheControllerDispatcher;
 import org.killbill.billing.util.callcontext.InternalCallContextFactory;
@@ -32,13 +34,15 @@ import org.skife.jdbi.v2.IDBI;
 import com.google.common.collect.Iterables;
 import com.google.inject.Inject;
 
+import static org.killbill.billing.util.glue.IDBISetup.MAIN_RO_IDBI_NAMED;
+
 public class OverdueAsyncBusPoster extends DefaultOverduePosterBase {
 
     @Inject
     public OverdueAsyncBusPoster(final NotificationQueueService notificationQueueService,
-                                 final IDBI dbi, final Clock clock, final CacheControllerDispatcher cacheControllerDispatcher,
+                                 final IDBI dbi, @Named(MAIN_RO_IDBI_NAMED) final IDBI roDbi, final Clock clock, final CacheControllerDispatcher cacheControllerDispatcher,
                                  final NonEntityDao nonEntityDao, final InternalCallContextFactory internalCallContextFactory) {
-        super(notificationQueueService, dbi, clock, cacheControllerDispatcher, nonEntityDao, internalCallContextFactory);
+        super(notificationQueueService, dbi, roDbi, clock, cacheControllerDispatcher, nonEntityDao, internalCallContextFactory);
     }
 
     @Override
diff --git a/overdue/src/main/java/org/killbill/billing/overdue/notification/OverdueCheckPoster.java b/overdue/src/main/java/org/killbill/billing/overdue/notification/OverdueCheckPoster.java
index 3fc227a..1f30971 100644
--- a/overdue/src/main/java/org/killbill/billing/overdue/notification/OverdueCheckPoster.java
+++ b/overdue/src/main/java/org/killbill/billing/overdue/notification/OverdueCheckPoster.java
@@ -20,6 +20,8 @@ package org.killbill.billing.overdue.notification;
 
 import java.util.Iterator;
 
+import javax.inject.Named;
+
 import org.joda.time.DateTime;
 import org.killbill.billing.util.cache.CacheControllerDispatcher;
 import org.killbill.billing.util.callcontext.InternalCallContextFactory;
@@ -33,13 +35,15 @@ import org.skife.jdbi.v2.IDBI;
 
 import com.google.inject.Inject;
 
+import static org.killbill.billing.util.glue.IDBISetup.MAIN_RO_IDBI_NAMED;
+
 public class OverdueCheckPoster extends DefaultOverduePosterBase {
 
     @Inject
     public OverdueCheckPoster(final NotificationQueueService notificationQueueService,
-                              final IDBI dbi, final Clock clock, final CacheControllerDispatcher cacheControllerDispatcher,
+                              final IDBI dbi, @Named(MAIN_RO_IDBI_NAMED) final IDBI roDbi, final Clock clock, final CacheControllerDispatcher cacheControllerDispatcher,
                               final NonEntityDao nonEntityDao, final InternalCallContextFactory internalCallContextFactory) {
-        super(notificationQueueService, dbi, clock, cacheControllerDispatcher, nonEntityDao, internalCallContextFactory);
+        super(notificationQueueService, dbi, roDbi, clock, cacheControllerDispatcher, nonEntityDao, internalCallContextFactory);
     }
 
     @Override
diff --git a/overdue/src/test/java/org/killbill/billing/overdue/notification/TestDefaultOverdueCheckPoster.java b/overdue/src/test/java/org/killbill/billing/overdue/notification/TestDefaultOverdueCheckPoster.java
index ca991a2..b733c7b 100644
--- a/overdue/src/test/java/org/killbill/billing/overdue/notification/TestDefaultOverdueCheckPoster.java
+++ b/overdue/src/test/java/org/killbill/billing/overdue/notification/TestDefaultOverdueCheckPoster.java
@@ -1,7 +1,7 @@
 /*
  * Copyright 2010-2013 Ning, Inc.
- * Copyright 2014-2017 Groupon, Inc
- * Copyright 2014-2017 The Billing Project, LLC
+ * Copyright 2014-2018 Groupon, Inc
+ * Copyright 2014-2018 The Billing Project, LLC
  *
  * The Billing Project licenses this file to you under the Apache License, version 2.0
  * (the "License"); you may not use this file except in compliance with the
@@ -52,7 +52,7 @@ public class TestDefaultOverdueCheckPoster extends OverdueTestSuiteWithEmbeddedD
     @BeforeMethod(groups = "slow")
     public void beforeMethod() throws Exception {
         super.beforeMethod();
-        entitySqlDaoTransactionalJdbiWrapper = new EntitySqlDaoTransactionalJdbiWrapper(dbi, clock, cacheControllerDispatcher, nonEntityDao, internalCallContextFactory);
+        entitySqlDaoTransactionalJdbiWrapper = new EntitySqlDaoTransactionalJdbiWrapper(dbi, roDbi, clock, cacheControllerDispatcher, nonEntityDao, internalCallContextFactory);
 
         overdueQueue = notificationQueueService.getNotificationQueue(DefaultOverdueService.OVERDUE_SERVICE_NAME,
                                                                      OverdueCheckNotifier.OVERDUE_CHECK_NOTIFIER_QUEUE);
diff --git a/payment/src/main/java/org/killbill/billing/payment/dao/DefaultPaymentDao.java b/payment/src/main/java/org/killbill/billing/payment/dao/DefaultPaymentDao.java
index 1256398..766f15c 100644
--- a/payment/src/main/java/org/killbill/billing/payment/dao/DefaultPaymentDao.java
+++ b/payment/src/main/java/org/killbill/billing/payment/dao/DefaultPaymentDao.java
@@ -29,6 +29,7 @@ import java.util.regex.Pattern;
 
 import javax.annotation.Nullable;
 import javax.inject.Inject;
+import javax.inject.Named;
 
 import org.joda.time.DateTime;
 import org.killbill.billing.ErrorCode;
@@ -73,6 +74,8 @@ import com.google.common.collect.Collections2;
 import com.google.common.collect.ImmutableList;
 import com.google.common.collect.Iterables;
 
+import static org.killbill.billing.util.glue.IDBISetup.MAIN_RO_IDBI_NAMED;
+
 public class DefaultPaymentDao extends EntityDaoBase<PaymentModelDao, Payment, PaymentApiException> implements PaymentDao {
 
     private static final Logger log = LoggerFactory.getLogger(DefaultPaymentDao.class);
@@ -82,9 +85,9 @@ public class DefaultPaymentDao extends EntityDaoBase<PaymentModelDao, Payment, P
     private final Clock clock;
 
     @Inject
-    public DefaultPaymentDao(final IDBI dbi, final Clock clock, final CacheControllerDispatcher cacheControllerDispatcher,
+    public DefaultPaymentDao(final IDBI dbi, @Named(MAIN_RO_IDBI_NAMED) final IDBI roDbi, final Clock clock, final CacheControllerDispatcher cacheControllerDispatcher,
                              final NonEntityDao nonEntityDao, final InternalCallContextFactory internalCallContextFactory, final PersistentBus eventBus) {
-        super(new EntitySqlDaoTransactionalJdbiWrapper(dbi, clock, cacheControllerDispatcher, nonEntityDao, internalCallContextFactory), PaymentSqlDao.class);
+        super(new EntitySqlDaoTransactionalJdbiWrapper(dbi, roDbi, clock, cacheControllerDispatcher, nonEntityDao, internalCallContextFactory), PaymentSqlDao.class);
         this.paginationHelper = new DefaultPaginationSqlDaoHelper(transactionalSqlDao);
         this.eventBus = eventBus;
         this.clock = clock;
@@ -148,6 +151,7 @@ public class DefaultPaymentDao extends EntityDaoBase<PaymentModelDao, Payment, P
                                                   public Long getCount(final PaymentAttemptSqlDao sqlDao, final InternalTenantContext context) {
                                                       return sqlDao.getCountByStateNameAcrossTenants(stateName, createdBefore);
                                                   }
+
                                                   @Override
                                                   public Iterator<PaymentAttemptModelDao> build(final PaymentAttemptSqlDao sqlDao, final Long offset, final Long limit, final Ordering ordering, final InternalTenantContext context) {
                                                       return sqlDao.getByStateNameAcrossTenants(stateName, createdBefore, offset, limit, ordering.toString());
@@ -538,7 +542,6 @@ public class DefaultPaymentDao extends EntityDaoBase<PaymentModelDao, Payment, P
         });
     }
 
-
     @Override
     public Pagination<PaymentMethodModelDao> searchPaymentMethods(final String searchKey, final Long offset, final Long limit, final InternalTenantContext context) {
         return paginationHelper.getPagination(PaymentMethodSqlDao.class,
diff --git a/profiles/killbill/src/main/java/org/killbill/billing/server/modules/KillbillJdbcTenantRealmProvider.java b/profiles/killbill/src/main/java/org/killbill/billing/server/modules/KillbillJdbcTenantRealmProvider.java
index 5774818..4e7ca1c 100644
--- a/profiles/killbill/src/main/java/org/killbill/billing/server/modules/KillbillJdbcTenantRealmProvider.java
+++ b/profiles/killbill/src/main/java/org/killbill/billing/server/modules/KillbillJdbcTenantRealmProvider.java
@@ -1,6 +1,6 @@
 /*
- * Copyright 2014-2017 Groupon, Inc
- * Copyright 2014-2017 The Billing Project, LLC
+ * Copyright 2014-2018 Groupon, Inc
+ * Copyright 2014-2018 The Billing Project, LLC
  *
  * The Billing Project licenses this file to you under the Apache License, version 2.0
  * (the "License"); you may not use this file except in compliance with the
@@ -27,6 +27,8 @@ import org.killbill.billing.util.config.definition.SecurityConfig;
 import com.google.inject.Inject;
 import com.google.inject.Provider;
 
+import static org.killbill.billing.platform.glue.KillBillPlatformModuleBase.SHIRO_DATA_SOURCE_ID;
+
 public class KillbillJdbcTenantRealmProvider implements Provider<KillbillJdbcTenantRealm> {
 
     private final SecurityConfig securityConfig;
@@ -34,7 +36,7 @@ public class KillbillJdbcTenantRealmProvider implements Provider<KillbillJdbcTen
     private final DataSource dataSource;
 
     @Inject
-    public KillbillJdbcTenantRealmProvider(final SecurityConfig securityConfig, final CacheManager cacheManager, @Named(KillbillPlatformModule.SHIRO_DATA_SOURCE_ID_NAMED) final DataSource dataSource) {
+    public KillbillJdbcTenantRealmProvider(final SecurityConfig securityConfig, final CacheManager cacheManager, @Named(SHIRO_DATA_SOURCE_ID) final DataSource dataSource) {
         this.securityConfig = securityConfig;
         this.cacheManager = cacheManager;
         this.dataSource = dataSource;
diff --git a/profiles/killbill/src/main/java/org/killbill/billing/server/modules/KillbillServerModule.java b/profiles/killbill/src/main/java/org/killbill/billing/server/modules/KillbillServerModule.java
index b182e9e..6ffbc2a 100644
--- a/profiles/killbill/src/main/java/org/killbill/billing/server/modules/KillbillServerModule.java
+++ b/profiles/killbill/src/main/java/org/killbill/billing/server/modules/KillbillServerModule.java
@@ -99,7 +99,6 @@ import com.google.inject.name.Names;
 
 public class KillbillServerModule extends KillbillPlatformModule {
 
-    public static final String SHIRO_DATA_SOURCE_ID = "shiro";
     public static final String STATIC_CONFIG = "StaticConfig";
 
     public KillbillServerModule(final ServletContext servletContext, final KillbillServerConfig serverConfig, final KillbillConfigSource configSource) {
@@ -139,7 +138,14 @@ public class KillbillServerModule extends KillbillPlatformModule {
 
         // Same database, but different pool: clone the object so the shutdown sequence cleans the pool properly
         shiroEmbeddedDB = new KillBillEmbeddedDBProvider(daoConfig).get();
-        bind(EmbeddedDB.class).annotatedWith(Names.named(SHIRO_DATA_SOURCE_ID_NAMED)).toInstance(shiroEmbeddedDB);
+        bind(EmbeddedDB.class).annotatedWith(Names.named(SHIRO_DATA_SOURCE_ID)).toInstance(shiroEmbeddedDB);
+
+        if (mainRoDataSourceConfig.isEnabled()) {
+            mainRoEmbeddedDB = new KillBillEmbeddedDBProvider(mainRoDataSourceConfig).get();
+        } else {
+            mainRoEmbeddedDB = mainEmbeddedDB;
+        }
+        bind(EmbeddedDB.class).annotatedWith(Names.named(MAIN_RO_DATA_SOURCE_ID)).toInstance(mainRoEmbeddedDB);
     }
 
     @Override
diff --git a/profiles/killbill/src/test/java/org/killbill/billing/server/security/TestKillbillJdbcTenantRealm.java b/profiles/killbill/src/test/java/org/killbill/billing/server/security/TestKillbillJdbcTenantRealm.java
index b5b51ce..39b1b13 100644
--- a/profiles/killbill/src/test/java/org/killbill/billing/server/security/TestKillbillJdbcTenantRealm.java
+++ b/profiles/killbill/src/test/java/org/killbill/billing/server/security/TestKillbillJdbcTenantRealm.java
@@ -1,7 +1,7 @@
 /*
  * Copyright 2010-2013 Ning, Inc.
- * Copyright 2014-2016 Groupon, Inc
- * Copyright 2014-2016 The Billing Project, LLC
+ * Copyright 2014-2018 Groupon, Inc
+ * Copyright 2014-2018 The Billing Project, LLC
  *
  * The Billing Project licenses this file to you under the Apache License, version 2.0
  * (the "License"); you may not use this file except in compliance with the
@@ -51,7 +51,7 @@ public class TestKillbillJdbcTenantRealm extends TestJaxrsBase {
         super.beforeMethod();
 
         // Create the tenant
-        final DefaultTenantDao tenantDao = new DefaultTenantDao(dbi, clock, cacheControllerDispatcher, new DefaultNonEntityDao(dbi), Mockito.mock(InternalCallContextFactory.class), securityConfig);
+        final DefaultTenantDao tenantDao = new DefaultTenantDao(dbi, roDbi, clock, cacheControllerDispatcher, new DefaultNonEntityDao(dbi), Mockito.mock(InternalCallContextFactory.class), securityConfig);
         tenant = new DefaultTenant(UUID.randomUUID(), null, null, UUID.randomUUID().toString(),
                                    UUID.randomUUID().toString(), UUID.randomUUID().toString());
         tenantDao.create(new TenantModelDao(tenant), internalCallContext);
diff --git a/subscription/src/main/java/org/killbill/billing/subscription/engine/dao/DefaultSubscriptionDao.java b/subscription/src/main/java/org/killbill/billing/subscription/engine/dao/DefaultSubscriptionDao.java
index c56df6e..5337dc0 100644
--- a/subscription/src/main/java/org/killbill/billing/subscription/engine/dao/DefaultSubscriptionDao.java
+++ b/subscription/src/main/java/org/killbill/billing/subscription/engine/dao/DefaultSubscriptionDao.java
@@ -1,7 +1,7 @@
 /*
  * Copyright 2010-2013 Ning, Inc.
- * Copyright 2014-2017 Groupon, Inc
- * Copyright 2014-2017 The Billing Project, LLC
+ * Copyright 2014-2018 Groupon, Inc
+ * Copyright 2014-2018 The Billing Project, LLC
  *
  * The Billing Project licenses this file to you under the Apache License, version 2.0
  * (the "License"); you may not use this file except in compliance with the
@@ -34,6 +34,7 @@ import java.util.UUID;
 
 import javax.annotation.Nullable;
 import javax.inject.Inject;
+import javax.inject.Named;
 
 import org.joda.time.DateTime;
 import org.killbill.billing.ErrorCode;
@@ -113,6 +114,8 @@ import com.google.common.collect.ImmutableList;
 import com.google.common.collect.Iterables;
 import com.google.common.collect.Multimap;
 
+import static org.killbill.billing.util.glue.IDBISetup.MAIN_RO_IDBI_NAMED;
+
 public class DefaultSubscriptionDao extends EntityDaoBase<SubscriptionBundleModelDao, SubscriptionBaseBundle, SubscriptionApiException> implements SubscriptionDao {
 
     private static final Logger log = LoggerFactory.getLogger(DefaultSubscriptionDao.class);
@@ -123,11 +126,11 @@ public class DefaultSubscriptionDao extends EntityDaoBase<SubscriptionBundleMode
     private final PersistentBus eventBus;
 
     @Inject
-    public DefaultSubscriptionDao(final IDBI dbi, final Clock clock, final AddonUtils addonUtils,
+    public DefaultSubscriptionDao(final IDBI dbi, @Named(MAIN_RO_IDBI_NAMED) final IDBI roDbi, final Clock clock, final AddonUtils addonUtils,
                                   final NotificationQueueService notificationQueueService, final PersistentBus eventBus,
                                   final CacheControllerDispatcher cacheControllerDispatcher, final NonEntityDao nonEntityDao,
                                   final InternalCallContextFactory internalCallContextFactory) {
-        super(new EntitySqlDaoTransactionalJdbiWrapper(dbi, clock, cacheControllerDispatcher, nonEntityDao, internalCallContextFactory), BundleSqlDao.class);
+        super(new EntitySqlDaoTransactionalJdbiWrapper(dbi, roDbi, clock, cacheControllerDispatcher, nonEntityDao, internalCallContextFactory), BundleSqlDao.class);
         this.clock = clock;
         this.notificationQueueService = notificationQueueService;
         this.addonUtils = addonUtils;
@@ -255,7 +258,6 @@ public class DefaultSubscriptionDao extends EntityDaoBase<SubscriptionBundleMode
     @Override
     public SubscriptionBaseBundle createSubscriptionBundle(final DefaultSubscriptionBaseBundle bundle, final Catalog catalog, final boolean renameCancelledBundleIfExist, final InternalCallContext context) throws SubscriptionBaseApiException {
 
-
         return transactionalSqlDao.execute(SubscriptionBaseApiException.class, new EntitySqlDaoTransactionWrapper<SubscriptionBaseBundle>() {
 
             //
@@ -280,19 +282,18 @@ public class DefaultSubscriptionDao extends EntityDaoBase<SubscriptionBundleMode
                 if (existingBundleForAccount != null) {
                     final List<SubscriptionModelDao> accountSubscriptions = entitySqlDaoWrapperFactory.become(SubscriptionSqlDao.class).getByAccountRecordId(context);
                     if (accountSubscriptions == null ||
-                        ! Iterables.any(accountSubscriptions, new Predicate<SubscriptionModelDao>() {
-                        @Override
-                        public boolean apply(final SubscriptionModelDao input) {
-                            return input.getBundleId().equals(existingBundleForAccount.getId());
-                        }
-                    })) {
+                        !Iterables.any(accountSubscriptions, new Predicate<SubscriptionModelDao>() {
+                            @Override
+                            public boolean apply(final SubscriptionModelDao input) {
+                                return input.getBundleId().equals(existingBundleForAccount.getId());
+                            }
+                        })) {
                         return SubscriptionBundleModelDao.toSubscriptionBundle(existingBundleForAccount);
                     }
                 }
                 return null;
             }
 
-
             @Override
             public SubscriptionBaseBundle inTransaction(final EntitySqlDaoWrapperFactory entitySqlDaoWrapperFactory) throws Exception {
                 final List<SubscriptionBundleModelDao> existingBundles = bundle.getExternalKey() == null ? ImmutableList.<SubscriptionBundleModelDao>of()
@@ -662,10 +663,9 @@ public class DefaultSubscriptionDao extends EntityDaoBase<SubscriptionBundleMode
 
     @Override
     public void undoChangePlan(final DefaultSubscriptionBase subscription, final List<SubscriptionBaseEvent> undoChangePlanEvents, final InternalCallContext context) {
-            undoOperation(subscription, undoChangePlanEvents, ApiEventType.CHANGE, SubscriptionBaseTransitionType.UNDO_CHANGE, context);
+        undoOperation(subscription, undoChangePlanEvents, ApiEventType.CHANGE, SubscriptionBaseTransitionType.UNDO_CHANGE, context);
     }
 
-
     private void undoOperation(final DefaultSubscriptionBase subscription, final List<SubscriptionBaseEvent> inputEvents, final ApiEventType targetOperation, final SubscriptionBaseTransitionType transitionType, final InternalCallContext context) {
 
         final InternalCallContext contextWithUpdatedDate = contextWithUpdatedDate(context);
@@ -779,12 +779,11 @@ public class DefaultSubscriptionDao extends EntityDaoBase<SubscriptionBundleMode
         });
     }
 
-
     private List<SubscriptionBaseEvent> filterSubscriptionBaseEvents(final Collection<SubscriptionEventModelDao> models) {
         final Collection<SubscriptionEventModelDao> filteredModels = Collections2.filter(models, new Predicate<SubscriptionEventModelDao>() {
             @Override
             public boolean apply(@Nullable final SubscriptionEventModelDao input) {
-                return input.getUserType() != ApiEventType.UNCANCEL && input.getUserType() != ApiEventType.UNDO_CHANGE ;
+                return input.getUserType() != ApiEventType.UNCANCEL && input.getUserType() != ApiEventType.UNDO_CHANGE;
             }
         });
         return new ArrayList<SubscriptionBaseEvent>(Collections2.transform(filteredModels, new Function<SubscriptionEventModelDao, SubscriptionBaseEvent>() {
@@ -1038,7 +1037,7 @@ public class DefaultSubscriptionDao extends EntityDaoBase<SubscriptionBundleMode
 
     @Override
     public void transfer(final UUID srcAccountId, final UUID destAccountId, final BundleTransferData bundleTransferData,
-                         final List<TransferCancelData> transferCancelData,  final Catalog catalog, final InternalCallContext fromContext, final InternalCallContext toContext) {
+                         final List<TransferCancelData> transferCancelData, final Catalog catalog, final InternalCallContext fromContext, final InternalCallContext toContext) {
 
         transactionalSqlDao.execute(new EntitySqlDaoTransactionWrapper<Void>() {
             @Override
@@ -1049,7 +1048,6 @@ public class DefaultSubscriptionDao extends EntityDaoBase<SubscriptionBundleMode
                     cancelSubscriptionFromTransaction(cancel.getSubscription(), cancel.getCancelEvent(), entitySqlDaoWrapperFactory, catalog, fromContext, 0);
                 }
 
-
                 // Rename externalKey from source bundle
                 final BundleSqlDao bundleSqlDao = entitySqlDaoWrapperFactory.become(BundleSqlDao.class);
                 bundleSqlDao.renameBundleExternalKey(bundleTransferData.getData().getExternalKey(), "tsf", fromContext);
@@ -1226,7 +1224,6 @@ public class DefaultSubscriptionDao extends EntityDaoBase<SubscriptionBundleMode
         return subscriptionWithNewEvent;
     }
 
-
     private InternalCallContext contextWithUpdatedDate(final InternalCallContext input) {
         return new InternalCallContext(input, clock.getUTCNow());
     }
diff --git a/subscription/src/test/java/org/killbill/billing/subscription/engine/dao/MockSubscriptionDaoSql.java b/subscription/src/test/java/org/killbill/billing/subscription/engine/dao/MockSubscriptionDaoSql.java
index 790ef04..3727c08 100644
--- a/subscription/src/test/java/org/killbill/billing/subscription/engine/dao/MockSubscriptionDaoSql.java
+++ b/subscription/src/test/java/org/killbill/billing/subscription/engine/dao/MockSubscriptionDaoSql.java
@@ -1,7 +1,7 @@
 /*
  * Copyright 2010-2013 Ning, Inc.
- * Copyright 2014-2016 Groupon, Inc
- * Copyright 2014-2016 The Billing Project, LLC
+ * Copyright 2014-2018 Groupon, Inc
+ * Copyright 2014-2018 The Billing Project, LLC
  *
  * The Billing Project licenses this file to you under the Apache License, version 2.0
  * (the "License"); you may not use this file except in compliance with the
@@ -18,26 +18,27 @@
 
 package org.killbill.billing.subscription.engine.dao;
 
-import org.killbill.billing.catalog.api.CatalogInternalApi;
-import org.killbill.billing.util.callcontext.InternalCallContextFactory;
-import org.skife.jdbi.v2.IDBI;
+import javax.inject.Named;
 
-import org.killbill.bus.api.PersistentBus;
-import org.killbill.billing.catalog.api.CatalogService;
-import org.killbill.clock.Clock;
-import org.killbill.notificationq.api.NotificationQueueService;
 import org.killbill.billing.subscription.engine.addon.AddonUtils;
 import org.killbill.billing.util.cache.CacheControllerDispatcher;
+import org.killbill.billing.util.callcontext.InternalCallContextFactory;
 import org.killbill.billing.util.dao.NonEntityDao;
+import org.killbill.bus.api.PersistentBus;
+import org.killbill.clock.Clock;
+import org.killbill.notificationq.api.NotificationQueueService;
+import org.skife.jdbi.v2.IDBI;
 
 import com.google.inject.Inject;
 
+import static org.killbill.billing.util.glue.IDBISetup.MAIN_RO_IDBI_NAMED;
+
 public class MockSubscriptionDaoSql extends DefaultSubscriptionDao {
 
     @Inject
-    public MockSubscriptionDaoSql(final IDBI dbi, final Clock clock, final AddonUtils addonUtils, final NotificationQueueService notificationQueueService,
+    public MockSubscriptionDaoSql(final IDBI dbi, @Named(MAIN_RO_IDBI_NAMED) final IDBI roDbi, final Clock clock, final AddonUtils addonUtils, final NotificationQueueService notificationQueueService,
                                   final PersistentBus eventBus, final CacheControllerDispatcher cacheControllerDispatcher,
                                   final NonEntityDao nonEntityDao, final InternalCallContextFactory internalCallContextFactory) {
-        super(dbi, clock, addonUtils, notificationQueueService, eventBus,  cacheControllerDispatcher, nonEntityDao, internalCallContextFactory);
+        super(dbi, roDbi, clock, addonUtils, notificationQueueService, eventBus, cacheControllerDispatcher, nonEntityDao, internalCallContextFactory);
     }
 }
diff --git a/tenant/src/main/java/org/killbill/billing/tenant/dao/DefaultTenantBroadcastDao.java b/tenant/src/main/java/org/killbill/billing/tenant/dao/DefaultTenantBroadcastDao.java
index 5fa4996..30ef282 100644
--- a/tenant/src/main/java/org/killbill/billing/tenant/dao/DefaultTenantBroadcastDao.java
+++ b/tenant/src/main/java/org/killbill/billing/tenant/dao/DefaultTenantBroadcastDao.java
@@ -1,6 +1,6 @@
 /*
- * Copyright 2014-2016 Groupon, Inc
- * Copyright 2014-2016 The Billing Project, LLC
+ * Copyright 2014-2018 Groupon, Inc
+ * Copyright 2014-2018 The Billing Project, LLC
  *
  * The Billing Project licenses this file to you under the Apache License, version 2.0
  * (the "License"); you may not use this file except in compliance with the
@@ -20,6 +20,7 @@ package org.killbill.billing.tenant.dao;
 import java.util.List;
 
 import javax.inject.Inject;
+import javax.inject.Named;
 
 import org.killbill.billing.callcontext.InternalCallContext;
 import org.killbill.billing.tenant.api.TenantApiException;
@@ -32,12 +33,14 @@ import org.killbill.billing.util.entity.dao.EntitySqlDaoTransactionalJdbiWrapper
 import org.killbill.clock.Clock;
 import org.skife.jdbi.v2.IDBI;
 
+import static org.killbill.billing.util.glue.IDBISetup.MAIN_RO_IDBI_NAMED;
+
 public class DefaultTenantBroadcastDao extends EntityDaoBase<TenantBroadcastModelDao, Entity, TenantApiException> implements TenantBroadcastDao {
 
     @Inject
-    public DefaultTenantBroadcastDao(final IDBI dbi, final Clock clock, final CacheControllerDispatcher cacheControllerDispatcher,
+    public DefaultTenantBroadcastDao(final IDBI dbi, @Named(MAIN_RO_IDBI_NAMED) final IDBI roDbi, final Clock clock, final CacheControllerDispatcher cacheControllerDispatcher,
                                      final NonEntityDao nonEntityDao, final InternalCallContextFactory internalCallContextFactory) {
-        super(new EntitySqlDaoTransactionalJdbiWrapper(dbi, clock, cacheControllerDispatcher, nonEntityDao, internalCallContextFactory), TenantBroadcastSqlDao.class);
+        super(new EntitySqlDaoTransactionalJdbiWrapper(dbi, roDbi, clock, cacheControllerDispatcher, nonEntityDao, internalCallContextFactory), TenantBroadcastSqlDao.class);
     }
 
     @Override
diff --git a/tenant/src/main/java/org/killbill/billing/tenant/dao/DefaultTenantDao.java b/tenant/src/main/java/org/killbill/billing/tenant/dao/DefaultTenantDao.java
index 18f2238..301b390 100644
--- a/tenant/src/main/java/org/killbill/billing/tenant/dao/DefaultTenantDao.java
+++ b/tenant/src/main/java/org/killbill/billing/tenant/dao/DefaultTenantDao.java
@@ -1,7 +1,7 @@
 /*
  * Copyright 2010-2013 Ning, Inc.
- * Copyright 2014-2017 Groupon, Inc
- * Copyright 2014-2017 The Billing Project, LLC
+ * Copyright 2014-2018 Groupon, Inc
+ * Copyright 2014-2018 The Billing Project, LLC
  *
  * The Billing Project licenses this file to you under the Apache License, version 2.0
  * (the "License"); you may not use this file except in compliance with the
@@ -21,6 +21,8 @@ package org.killbill.billing.tenant.dao;
 import java.util.List;
 import java.util.UUID;
 
+import javax.inject.Named;
+
 import org.apache.shiro.authc.AuthenticationInfo;
 import org.apache.shiro.authc.SimpleAuthenticationInfo;
 import org.apache.shiro.codec.Base64;
@@ -56,6 +58,8 @@ import com.google.common.collect.ImmutableList;
 import com.google.common.collect.Iterables;
 import com.google.inject.Inject;
 
+import static org.killbill.billing.util.glue.IDBISetup.MAIN_RO_IDBI_NAMED;
+
 public class DefaultTenantDao extends EntityDaoBase<TenantModelDao, Tenant, TenantApiException> implements TenantDao {
 
     private final RandomNumberGenerator rng = new SecureRandomNumberGenerator();
@@ -63,9 +67,9 @@ public class DefaultTenantDao extends EntityDaoBase<TenantModelDao, Tenant, Tena
     private final SecurityConfig securityConfig;
 
     @Inject
-    public DefaultTenantDao(final IDBI dbi, final Clock clock, final CacheControllerDispatcher cacheControllerDispatcher,
+    public DefaultTenantDao(final IDBI dbi, @Named(MAIN_RO_IDBI_NAMED) final IDBI roDbi, final Clock clock, final CacheControllerDispatcher cacheControllerDispatcher,
                             final NonEntityDao nonEntityDao, final InternalCallContextFactory internalCallContextFactory, final SecurityConfig securityConfig) {
-        super(new EntitySqlDaoTransactionalJdbiWrapper(dbi, clock, cacheControllerDispatcher, nonEntityDao, internalCallContextFactory), TenantSqlDao.class);
+        super(new EntitySqlDaoTransactionalJdbiWrapper(dbi, roDbi, clock, cacheControllerDispatcher, nonEntityDao, internalCallContextFactory), TenantSqlDao.class);
         this.securityConfig = securityConfig;
     }
 
diff --git a/tenant/src/main/java/org/killbill/billing/tenant/dao/NoCachingTenantBroadcastDao.java b/tenant/src/main/java/org/killbill/billing/tenant/dao/NoCachingTenantBroadcastDao.java
index eef661e..2c5a1d1 100644
--- a/tenant/src/main/java/org/killbill/billing/tenant/dao/NoCachingTenantBroadcastDao.java
+++ b/tenant/src/main/java/org/killbill/billing/tenant/dao/NoCachingTenantBroadcastDao.java
@@ -1,6 +1,6 @@
 /*
- * Copyright 2014-2016 Groupon, Inc
- * Copyright 2014-2016 The Billing Project, LLC
+ * Copyright 2014-2018 Groupon, Inc
+ * Copyright 2014-2018 The Billing Project, LLC
  *
  * The Billing Project licenses this file to you under the Apache License, version 2.0
  * (the "License"); you may not use this file except in compliance with the
@@ -37,11 +37,13 @@ import org.killbill.billing.util.entity.dao.EntitySqlDaoWrapperFactory;
 import org.killbill.clock.Clock;
 import org.skife.jdbi.v2.IDBI;
 
+import static org.killbill.billing.util.glue.IDBISetup.MAIN_RO_IDBI_NAMED;
+
 public class NoCachingTenantBroadcastDao extends EntityDaoBase<TenantBroadcastModelDao, Entity, TenantApiException> implements TenantBroadcastDao {
 
     @Inject
-    public NoCachingTenantBroadcastDao(final IDBI dbi, final Clock clock, @Named(DefaultTenantModule.NO_CACHING_TENANT) final InternalCallContextFactory internalCallContextFactory) {
-        super(new EntitySqlDaoTransactionalJdbiWrapper(dbi, clock, null, null, internalCallContextFactory), TenantBroadcastSqlDao.class);
+    public NoCachingTenantBroadcastDao(final IDBI dbi, @Named(MAIN_RO_IDBI_NAMED) final IDBI roDbi, final Clock clock, @Named(DefaultTenantModule.NO_CACHING_TENANT) final InternalCallContextFactory internalCallContextFactory) {
+        super(new EntitySqlDaoTransactionalJdbiWrapper(dbi, roDbi, clock, null, null, internalCallContextFactory), TenantBroadcastSqlDao.class);
     }
 
     @Override
diff --git a/tenant/src/main/java/org/killbill/billing/tenant/dao/NoCachingTenantDao.java b/tenant/src/main/java/org/killbill/billing/tenant/dao/NoCachingTenantDao.java
index 8f0b841..fa7a361 100644
--- a/tenant/src/main/java/org/killbill/billing/tenant/dao/NoCachingTenantDao.java
+++ b/tenant/src/main/java/org/killbill/billing/tenant/dao/NoCachingTenantDao.java
@@ -1,6 +1,6 @@
 /*
- * Copyright 2014-2016 Groupon, Inc
- * Copyright 2014-2016 The Billing Project, LLC
+ * Copyright 2014-2018 Groupon, Inc
+ * Copyright 2014-2018 The Billing Project, LLC
  *
  * The Billing Project licenses this file to you under the Apache License, version 2.0
  * (the "License"); you may not use this file except in compliance with the
@@ -41,6 +41,8 @@ import com.google.common.base.Function;
 import com.google.common.collect.Collections2;
 import com.google.inject.Inject;
 
+import static org.killbill.billing.util.glue.IDBISetup.MAIN_RO_IDBI_NAMED;
+
 /**
  * This is a special implementation of the TenantDao that does not rely on caching (CacheControllerDispatcher is not injected and passed
  * to the EntitySqlDaoWrapperInvocationHandler. It only implements the set of operations that does not require caching:
@@ -54,8 +56,8 @@ import com.google.inject.Inject;
 public class NoCachingTenantDao extends EntityDaoBase<TenantModelDao, Tenant, TenantApiException> implements TenantDao {
 
     @Inject
-    public NoCachingTenantDao(final IDBI dbi, final Clock clock, @Named(DefaultTenantModule.NO_CACHING_TENANT) final InternalCallContextFactory internalCallContextFactory) {
-        super(new EntitySqlDaoTransactionalJdbiWrapper(dbi, clock, null, null, internalCallContextFactory), TenantSqlDao.class);
+    public NoCachingTenantDao(final IDBI dbi, @Named(MAIN_RO_IDBI_NAMED) final IDBI roDbi, final Clock clock, @Named(DefaultTenantModule.NO_CACHING_TENANT) final InternalCallContextFactory internalCallContextFactory) {
+        super(new EntitySqlDaoTransactionalJdbiWrapper(dbi, roDbi, clock, null, null, internalCallContextFactory), TenantSqlDao.class);
     }
 
     @Override
diff --git a/util/src/main/java/org/killbill/billing/util/audit/dao/DefaultAuditDao.java b/util/src/main/java/org/killbill/billing/util/audit/dao/DefaultAuditDao.java
index 13b75f5..f9b6f07 100644
--- a/util/src/main/java/org/killbill/billing/util/audit/dao/DefaultAuditDao.java
+++ b/util/src/main/java/org/killbill/billing/util/audit/dao/DefaultAuditDao.java
@@ -1,7 +1,7 @@
 /*
  * Copyright 2010-2012 Ning, Inc.
- * Copyright 2014-2016 Groupon, Inc
- * Copyright 2014-2016 The Billing Project, LLC
+ * Copyright 2014-2018 Groupon, Inc
+ * Copyright 2014-2018 The Billing Project, LLC
  *
  * The Billing Project licenses this file to you under the Apache License, version 2.0
  * (the "License"); you may not use this file except in compliance with the
@@ -25,6 +25,7 @@ import java.util.Map;
 import java.util.UUID;
 
 import javax.inject.Inject;
+import javax.inject.Named;
 
 import org.killbill.billing.ObjectType;
 import org.killbill.billing.callcontext.InternalTenantContext;
@@ -52,15 +53,17 @@ import com.google.common.collect.ImmutableList;
 import com.google.common.collect.Iterators;
 import com.google.common.collect.Lists;
 
+import static org.killbill.billing.util.glue.IDBISetup.MAIN_RO_IDBI_NAMED;
+
 public class DefaultAuditDao implements AuditDao {
 
     private final NonEntitySqlDao nonEntitySqlDao;
     private final EntitySqlDaoTransactionalJdbiWrapper transactionalSqlDao;
 
     @Inject
-    public DefaultAuditDao(final IDBI dbi, final Clock clock, final CacheControllerDispatcher cacheControllerDispatcher, final NonEntityDao nonEntityDao, final InternalCallContextFactory internalCallContextFactory) {
+    public DefaultAuditDao(final IDBI dbi, @Named(MAIN_RO_IDBI_NAMED) final IDBI roDbi, final Clock clock, final CacheControllerDispatcher cacheControllerDispatcher, final NonEntityDao nonEntityDao, final InternalCallContextFactory internalCallContextFactory) {
         this.nonEntitySqlDao = dbi.onDemand(NonEntitySqlDao.class);
-        this.transactionalSqlDao = new EntitySqlDaoTransactionalJdbiWrapper(dbi, clock, cacheControllerDispatcher, nonEntityDao, internalCallContextFactory);
+        this.transactionalSqlDao = new EntitySqlDaoTransactionalJdbiWrapper(dbi, roDbi, clock, cacheControllerDispatcher, nonEntityDao, internalCallContextFactory);
     }
 
     @Override
diff --git a/util/src/main/java/org/killbill/billing/util/customfield/dao/DefaultCustomFieldDao.java b/util/src/main/java/org/killbill/billing/util/customfield/dao/DefaultCustomFieldDao.java
index d89595a..9b0be6f 100644
--- a/util/src/main/java/org/killbill/billing/util/customfield/dao/DefaultCustomFieldDao.java
+++ b/util/src/main/java/org/killbill/billing/util/customfield/dao/DefaultCustomFieldDao.java
@@ -1,7 +1,7 @@
 /*
  * Copyright 2010-2013 Ning, Inc.
- * Copyright 2014-2016 Groupon, Inc
- * Copyright 2014-2016 The Billing Project, LLC
+ * Copyright 2014-2018 Groupon, Inc
+ * Copyright 2014-2018 The Billing Project, LLC
  *
  * The Billing Project licenses this file to you under the Apache License, version 2.0
  * (the "License"); you may not use this file except in compliance with the
@@ -23,6 +23,7 @@ import java.util.List;
 import java.util.UUID;
 
 import javax.annotation.Nullable;
+import javax.inject.Named;
 
 import org.killbill.billing.BillingExceptionBase;
 import org.killbill.billing.ErrorCode;
@@ -58,6 +59,8 @@ import com.google.common.collect.ImmutableList;
 import com.google.common.collect.Iterables;
 import com.google.inject.Inject;
 
+import static org.killbill.billing.util.glue.IDBISetup.MAIN_RO_IDBI_NAMED;
+
 public class DefaultCustomFieldDao extends EntityDaoBase<CustomFieldModelDao, CustomField, CustomFieldApiException> implements CustomFieldDao {
 
     private static final Logger log = LoggerFactory.getLogger(DefaultCustomFieldDao.class);
@@ -65,9 +68,9 @@ public class DefaultCustomFieldDao extends EntityDaoBase<CustomFieldModelDao, Cu
     private final PersistentBus bus;
 
     @Inject
-    public DefaultCustomFieldDao(final IDBI dbi, final Clock clock, final CacheControllerDispatcher controllerDispatcher,
+    public DefaultCustomFieldDao(final IDBI dbi, @Named(MAIN_RO_IDBI_NAMED) final IDBI roDbi, final Clock clock, final CacheControllerDispatcher controllerDispatcher,
                                  final NonEntityDao nonEntityDao, final InternalCallContextFactory internalCallContextFactory, final PersistentBus bus) {
-        super(new EntitySqlDaoTransactionalJdbiWrapper(dbi, clock, controllerDispatcher, nonEntityDao, internalCallContextFactory), CustomFieldSqlDao.class);
+        super(new EntitySqlDaoTransactionalJdbiWrapper(dbi, roDbi, clock, controllerDispatcher, nonEntityDao, internalCallContextFactory), CustomFieldSqlDao.class);
         this.bus = bus;
     }
 
@@ -128,7 +131,7 @@ public class DefaultCustomFieldDao extends EntityDaoBase<CustomFieldModelDao, Cu
 
         transactionalSqlDao.execute(CustomFieldApiException.class, new EntitySqlDaoTransactionWrapper<Void>() {
 
-            private void validateCustomField(final CustomFieldModelDao input,  @Nullable CustomFieldModelDao existing) throws CustomFieldApiException {
+            private void validateCustomField(final CustomFieldModelDao input, @Nullable CustomFieldModelDao existing) throws CustomFieldApiException {
                 if (existing == null) {
                     throw new CustomFieldApiException(ErrorCode.CUSTOM_FIELD_DOES_NOT_EXISTS_FOR_ID, input.getId());
                 }
diff --git a/util/src/main/java/org/killbill/billing/util/entity/dao/EntitySqlDaoTransactionalJdbiWrapper.java b/util/src/main/java/org/killbill/billing/util/entity/dao/EntitySqlDaoTransactionalJdbiWrapper.java
index 4cfd83a..86b8361 100644
--- a/util/src/main/java/org/killbill/billing/util/entity/dao/EntitySqlDaoTransactionalJdbiWrapper.java
+++ b/util/src/main/java/org/killbill/billing/util/entity/dao/EntitySqlDaoTransactionalJdbiWrapper.java
@@ -45,7 +45,7 @@ public class EntitySqlDaoTransactionalJdbiWrapper {
     private final NonEntityDao nonEntityDao;
     private final InternalCallContextFactory internalCallContextFactory;
 
-    public EntitySqlDaoTransactionalJdbiWrapper(final IDBI dbi, final Clock clock, final CacheControllerDispatcher cacheControllerDispatcher,
+    public EntitySqlDaoTransactionalJdbiWrapper(final IDBI dbi, final IDBI roDbi, final Clock clock, final CacheControllerDispatcher cacheControllerDispatcher,
                                                 final NonEntityDao nonEntityDao, final InternalCallContextFactory internalCallContextFactory) {
         this.dbi = dbi;
         this.clock = clock;
diff --git a/util/src/main/java/org/killbill/billing/util/glue/IDBISetup.java b/util/src/main/java/org/killbill/billing/util/glue/IDBISetup.java
index 0e78d66..73d65ea 100644
--- a/util/src/main/java/org/killbill/billing/util/glue/IDBISetup.java
+++ b/util/src/main/java/org/killbill/billing/util/glue/IDBISetup.java
@@ -1,6 +1,6 @@
 /*
- * Copyright 2014-2017 Groupon, Inc
- * Copyright 2014-2017 The Billing Project, LLC
+ * Copyright 2014-2018 Groupon, Inc
+ * Copyright 2014-2018 The Billing Project, LLC
  *
  * The Billing Project licenses this file to you under the Apache License, version 2.0
  * (the "License"); you may not use this file except in compliance with the
@@ -46,6 +46,8 @@ import com.google.common.collect.ImmutableList.Builder;
 
 public class IDBISetup {
 
+    public static final String MAIN_RO_IDBI_NAMED = "main-ro";
+
     public static List<? extends ResultSetMapperFactory> mapperFactoriesToRegister() {
         final Builder<ResultSetMapperFactory> builder = ImmutableList.<ResultSetMapperFactory>builder();
         builder.add(new LowerToCamelBeanMapperFactory(SessionModelDao.class));
diff --git a/util/src/main/java/org/killbill/billing/util/security/shiro/realm/KillBillJdbcRealm.java b/util/src/main/java/org/killbill/billing/util/security/shiro/realm/KillBillJdbcRealm.java
index 6970497..4cb7d7b 100644
--- a/util/src/main/java/org/killbill/billing/util/security/shiro/realm/KillBillJdbcRealm.java
+++ b/util/src/main/java/org/killbill/billing/util/security/shiro/realm/KillBillJdbcRealm.java
@@ -1,6 +1,6 @@
 /*
- * Copyright 2014-2015 Groupon, Inc
- * Copyright 2014-2015 The Billing Project, LLC
+ * Copyright 2014-2018 Groupon, Inc
+ * Copyright 2014-2018 The Billing Project, LLC
  *
  * The Billing Project licenses this file to you under the Apache License, version 2.0
  * (the "License"); you may not use this file except in compliance with the
@@ -37,7 +37,7 @@ public class KillBillJdbcRealm extends JdbcRealm {
     private final SecurityConfig securityConfig;
 
     @Inject
-    public KillBillJdbcRealm(@Named(KillBillPlatformModuleBase.SHIRO_DATA_SOURCE_ID_NAMED) final DataSource dataSource, final SecurityConfig securityConfig) {
+    public KillBillJdbcRealm(@Named(KillBillPlatformModuleBase.SHIRO_DATA_SOURCE_ID) final DataSource dataSource, final SecurityConfig securityConfig) {
         super();
         this.dataSource = dataSource;
         this.securityConfig = securityConfig;
diff --git a/util/src/main/java/org/killbill/billing/util/tag/dao/DefaultTagDao.java b/util/src/main/java/org/killbill/billing/util/tag/dao/DefaultTagDao.java
index b6342ee..b3b647c 100644
--- a/util/src/main/java/org/killbill/billing/util/tag/dao/DefaultTagDao.java
+++ b/util/src/main/java/org/killbill/billing/util/tag/dao/DefaultTagDao.java
@@ -1,7 +1,7 @@
 /*
  * Copyright 2010-2013 Ning, Inc.
- * Copyright 2014-2016 Groupon, Inc
- * Copyright 2014-2016 The Billing Project, LLC
+ * Copyright 2014-2018 Groupon, Inc
+ * Copyright 2014-2018 The Billing Project, LLC
  *
  * The Billing Project licenses this file to you under the Apache License, version 2.0
  * (the "License"); you may not use this file except in compliance with the
@@ -22,25 +22,21 @@ import java.util.Iterator;
 import java.util.List;
 import java.util.UUID;
 
-import org.killbill.billing.util.callcontext.InternalCallContextFactory;
-import org.killbill.billing.util.entity.dao.DefaultPaginationSqlDaoHelper.Ordering;
-import org.skife.jdbi.v2.IDBI;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
+import javax.inject.Named;
 
 import org.killbill.billing.BillingExceptionBase;
 import org.killbill.billing.ErrorCode;
 import org.killbill.billing.ObjectType;
-import org.killbill.bus.api.PersistentBus;
 import org.killbill.billing.callcontext.InternalCallContext;
 import org.killbill.billing.callcontext.InternalTenantContext;
-import org.killbill.clock.Clock;
 import org.killbill.billing.events.TagInternalEvent;
 import org.killbill.billing.util.api.TagApiException;
 import org.killbill.billing.util.audit.ChangeType;
 import org.killbill.billing.util.cache.CacheControllerDispatcher;
+import org.killbill.billing.util.callcontext.InternalCallContextFactory;
 import org.killbill.billing.util.dao.NonEntityDao;
 import org.killbill.billing.util.entity.Pagination;
+import org.killbill.billing.util.entity.dao.DefaultPaginationSqlDaoHelper.Ordering;
 import org.killbill.billing.util.entity.dao.DefaultPaginationSqlDaoHelper.PaginationIteratorBuilder;
 import org.killbill.billing.util.entity.dao.EntityDaoBase;
 import org.killbill.billing.util.entity.dao.EntitySqlDao;
@@ -50,6 +46,11 @@ import org.killbill.billing.util.entity.dao.EntitySqlDaoWrapperFactory;
 import org.killbill.billing.util.tag.ControlTagType;
 import org.killbill.billing.util.tag.Tag;
 import org.killbill.billing.util.tag.api.user.TagEventBuilder;
+import org.killbill.bus.api.PersistentBus;
+import org.killbill.clock.Clock;
+import org.skife.jdbi.v2.IDBI;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 import com.google.common.base.Predicate;
 import com.google.common.collect.Collections2;
@@ -57,6 +58,8 @@ import com.google.common.collect.ImmutableList;
 import com.google.common.collect.Iterables;
 import com.google.inject.Inject;
 
+import static org.killbill.billing.util.glue.IDBISetup.MAIN_RO_IDBI_NAMED;
+
 public class DefaultTagDao extends EntityDaoBase<TagModelDao, Tag, TagApiException> implements TagDao {
 
     private static final Logger log = LoggerFactory.getLogger(DefaultTagDao.class);
@@ -65,9 +68,9 @@ public class DefaultTagDao extends EntityDaoBase<TagModelDao, Tag, TagApiExcepti
     private final PersistentBus bus;
 
     @Inject
-    public DefaultTagDao(final IDBI dbi, final TagEventBuilder tagEventBuilder, final PersistentBus bus, final Clock clock,
+    public DefaultTagDao(final IDBI dbi, @Named(MAIN_RO_IDBI_NAMED) final IDBI roDbi, final TagEventBuilder tagEventBuilder, final PersistentBus bus, final Clock clock,
                          final CacheControllerDispatcher controllerDispatcher, final NonEntityDao nonEntityDao, final InternalCallContextFactory internalCallContextFactory) {
-        super(new EntitySqlDaoTransactionalJdbiWrapper(dbi, clock, controllerDispatcher, nonEntityDao, internalCallContextFactory), TagSqlDao.class);
+        super(new EntitySqlDaoTransactionalJdbiWrapper(dbi, roDbi, clock, controllerDispatcher, nonEntityDao, internalCallContextFactory), TagSqlDao.class);
         this.tagEventBuilder = tagEventBuilder;
         this.bus = bus;
     }
diff --git a/util/src/main/java/org/killbill/billing/util/tag/dao/DefaultTagDefinitionDao.java b/util/src/main/java/org/killbill/billing/util/tag/dao/DefaultTagDefinitionDao.java
index dfa1331..9439e51 100644
--- a/util/src/main/java/org/killbill/billing/util/tag/dao/DefaultTagDefinitionDao.java
+++ b/util/src/main/java/org/killbill/billing/util/tag/dao/DefaultTagDefinitionDao.java
@@ -1,7 +1,7 @@
 /*
  * Copyright 2010-2011 Ning, Inc.
- * Copyright 2014-2016 Groupon, Inc
- * Copyright 2014-2016 The Billing Project, LLC
+ * Copyright 2014-2018 Groupon, Inc
+ * Copyright 2014-2018 The Billing Project, LLC
  *
  * The Billing Project licenses this file to you under the Apache License, version 2.0
  * (the "License"); you may not use this file except in compliance with the
@@ -22,9 +22,10 @@ import java.util.Collection;
 import java.util.Iterator;
 import java.util.LinkedList;
 import java.util.List;
-import java.util.Set;
 import java.util.UUID;
 
+import javax.inject.Named;
+
 import org.killbill.billing.BillingExceptionBase;
 import org.killbill.billing.ErrorCode;
 import org.killbill.billing.callcontext.InternalCallContext;
@@ -53,6 +54,8 @@ import com.google.common.collect.Collections2;
 import com.google.common.collect.Iterators;
 import com.google.inject.Inject;
 
+import static org.killbill.billing.util.glue.IDBISetup.MAIN_RO_IDBI_NAMED;
+
 public class DefaultTagDefinitionDao extends EntityDaoBase<TagDefinitionModelDao, TagDefinition, TagDefinitionApiException> implements TagDefinitionDao {
 
     private static final Logger log = LoggerFactory.getLogger(DefaultTagDefinitionDao.class);
@@ -60,11 +63,10 @@ public class DefaultTagDefinitionDao extends EntityDaoBase<TagDefinitionModelDao
     private final TagEventBuilder tagEventBuilder;
     private final PersistentBus bus;
 
-
     @Inject
-    public DefaultTagDefinitionDao(final IDBI dbi, final TagEventBuilder tagEventBuilder, final PersistentBus bus, final Clock clock,
+    public DefaultTagDefinitionDao(final IDBI dbi, @Named(MAIN_RO_IDBI_NAMED) final IDBI roDbi, final TagEventBuilder tagEventBuilder, final PersistentBus bus, final Clock clock,
                                    final CacheControllerDispatcher controllerDispatcher, final NonEntityDao nonEntityDao, final InternalCallContextFactory internalCallContextFactory) {
-        super(new EntitySqlDaoTransactionalJdbiWrapper(dbi, clock, controllerDispatcher, nonEntityDao, internalCallContextFactory), TagDefinitionSqlDao.class);
+        super(new EntitySqlDaoTransactionalJdbiWrapper(dbi, roDbi, clock, controllerDispatcher, nonEntityDao, internalCallContextFactory), TagDefinitionSqlDao.class);
         this.tagEventBuilder = tagEventBuilder;
         this.bus = bus;
     }
diff --git a/util/src/test/java/org/killbill/billing/GuicyKillbillTestNoDBModule.java b/util/src/test/java/org/killbill/billing/GuicyKillbillTestNoDBModule.java
index 9decb42..ba6716a 100644
--- a/util/src/test/java/org/killbill/billing/GuicyKillbillTestNoDBModule.java
+++ b/util/src/test/java/org/killbill/billing/GuicyKillbillTestNoDBModule.java
@@ -1,7 +1,7 @@
 /*
  * Copyright 2010-2013 Ning, Inc.
- * Copyright 2014 Groupon, Inc
- * Copyright 2014 The Billing Project, LLC
+ * Copyright 2014-2018 Groupon, Inc
+ * Copyright 2014-2018 The Billing Project, LLC
  *
  * The Billing Project licenses this file to you under the Apache License, version 2.0
  * (the "License"); you may not use this file except in compliance with the
@@ -20,6 +20,12 @@ package org.killbill.billing;
 
 import org.killbill.billing.platform.api.KillbillConfigSource;
 import org.killbill.billing.platform.test.glue.TestPlatformModuleNoDB;
+import org.killbill.billing.util.glue.IDBISetup;
+import org.skife.jdbi.v2.IDBI;
+
+import com.google.inject.Provides;
+import com.google.inject.Singleton;
+import com.google.inject.name.Named;
 
 public class GuicyKillbillTestNoDBModule extends GuicyKillbillTestModule {
 
@@ -33,4 +39,11 @@ public class GuicyKillbillTestNoDBModule extends GuicyKillbillTestModule {
 
         install(new TestPlatformModuleNoDB(configSource));
     }
+
+    @Provides
+    @Singleton
+    @Named(IDBISetup.MAIN_RO_IDBI_NAMED)
+    protected IDBI provideRoIDBI(final IDBI idbi) {
+        return idbi;
+    }
 }
diff --git a/util/src/test/java/org/killbill/billing/GuicyKillbillTestSuiteWithEmbeddedDB.java b/util/src/test/java/org/killbill/billing/GuicyKillbillTestSuiteWithEmbeddedDB.java
index 757b8d4..719cff7 100644
--- a/util/src/test/java/org/killbill/billing/GuicyKillbillTestSuiteWithEmbeddedDB.java
+++ b/util/src/test/java/org/killbill/billing/GuicyKillbillTestSuiteWithEmbeddedDB.java
@@ -1,7 +1,9 @@
 /*
  * Copyright 2010-2013 Ning, Inc.
+ * Copyright 2014-2018 Groupon, Inc
+ * Copyright 2014-2018 The Billing Project, LLC
  *
- * Ning licenses this file to you under the Apache License, version 2.0
+ * The Billing Project licenses this file to you under the Apache License, version 2.0
  * (the "License"); you may not use this file except in compliance with the
  * License.  You may obtain a copy of the License at:
  *
@@ -17,6 +19,7 @@
 package org.killbill.billing;
 
 import javax.inject.Inject;
+import javax.inject.Named;
 import javax.sql.DataSource;
 
 import org.killbill.billing.util.cache.CacheControllerDispatcher;
@@ -29,6 +32,8 @@ import org.testng.annotations.AfterSuite;
 import org.testng.annotations.BeforeMethod;
 import org.testng.annotations.BeforeSuite;
 
+import static org.killbill.billing.util.glue.IDBISetup.MAIN_RO_IDBI_NAMED;
+
 public class GuicyKillbillTestSuiteWithEmbeddedDB extends GuicyKillbillTestSuite {
 
     private static final Logger log = LoggerFactory.getLogger(GuicyKillbillTestSuiteWithEmbeddedDB.class);
@@ -43,8 +48,11 @@ public class GuicyKillbillTestSuiteWithEmbeddedDB extends GuicyKillbillTestSuite
     protected IDBI dbi;
 
     @Inject
-    protected CacheControllerDispatcher controlCacheDispatcher;
+    @Named(MAIN_RO_IDBI_NAMED)
+    protected IDBI roDbi;
 
+    @Inject
+    protected CacheControllerDispatcher controlCacheDispatcher;
 
     @BeforeSuite(groups = "slow")
     public void beforeSuite() throws Exception {
diff --git a/util/src/test/java/org/killbill/billing/GuicyKillbillTestWithEmbeddedDBModule.java b/util/src/test/java/org/killbill/billing/GuicyKillbillTestWithEmbeddedDBModule.java
index edeef1b..330d1a2 100644
--- a/util/src/test/java/org/killbill/billing/GuicyKillbillTestWithEmbeddedDBModule.java
+++ b/util/src/test/java/org/killbill/billing/GuicyKillbillTestWithEmbeddedDBModule.java
@@ -1,7 +1,7 @@
 /*
  * Copyright 2010-2013 Ning, Inc.
- * Copyright 2014-2016 Groupon, Inc
- * Copyright 2014-2016 The Billing Project, LLC
+ * Copyright 2014-2018 Groupon, Inc
+ * Copyright 2014-2018 The Billing Project, LLC
  *
  * The Billing Project licenses this file to you under the Apache License, version 2.0
  * (the "License"); you may not use this file except in compliance with the
@@ -22,6 +22,12 @@ import org.killbill.billing.platform.api.KillbillConfigSource;
 import org.killbill.billing.platform.test.PlatformDBTestingHelper;
 import org.killbill.billing.platform.test.config.TestKillbillConfigSource;
 import org.killbill.billing.platform.test.glue.TestPlatformModuleWithEmbeddedDB;
+import org.killbill.billing.util.glue.IDBISetup;
+import org.skife.jdbi.v2.IDBI;
+
+import com.google.inject.Provides;
+import com.google.inject.Singleton;
+import com.google.inject.name.Named;
 
 public class GuicyKillbillTestWithEmbeddedDBModule extends GuicyKillbillTestModule {
 
@@ -49,6 +55,13 @@ public class GuicyKillbillTestWithEmbeddedDBModule extends GuicyKillbillTestModu
             super(configSource, withOSGI, (TestKillbillConfigSource) configSource);
         }
 
+        @Provides
+        @Singleton
+        @Named(IDBISetup.MAIN_RO_IDBI_NAMED)
+        protected IDBI provideRoIDBIInAComplicatedWayBecauseOf627(final IDBI idbi) {
+            return idbi;
+        }
+
         @Override
         protected PlatformDBTestingHelper getPlatformDBTestingHelper() {
             return DBTestingHelper.get();
diff --git a/util/src/test/java/org/killbill/billing/util/cache/TestCache.java b/util/src/test/java/org/killbill/billing/util/cache/TestCache.java
index d24810c..dc2d689 100644
--- a/util/src/test/java/org/killbill/billing/util/cache/TestCache.java
+++ b/util/src/test/java/org/killbill/billing/util/cache/TestCache.java
@@ -60,7 +60,7 @@ public class TestCache extends UtilTestSuiteWithEmbeddedDB {
 
     @Test(groups = "slow")
     public void testCacheRecordId() throws Exception {
-        this.transactionalSqlDao = new EntitySqlDaoTransactionalJdbiWrapper(dbi, clock, controlCacheDispatcher, nonEntityDao, internalCallContextFactory);
+        this.transactionalSqlDao = new EntitySqlDaoTransactionalJdbiWrapper(dbi, roDbi, clock, controlCacheDispatcher, nonEntityDao, internalCallContextFactory);
         final TagModelDao tag = new TagModelDao(clock.getUTCNow(), UUID.randomUUID(), UUID.randomUUID(), ObjectType.TAG);
 
         // Verify we start with nothing in the cache
@@ -88,7 +88,7 @@ public class TestCache extends UtilTestSuiteWithEmbeddedDB {
 
     @Test(groups = "slow")
     public void testAllCachesAfterGetById() throws Exception {
-        this.transactionalSqlDao = new EntitySqlDaoTransactionalJdbiWrapper(dbi, clock, controlCacheDispatcher, nonEntityDao, internalCallContextFactory);
+        this.transactionalSqlDao = new EntitySqlDaoTransactionalJdbiWrapper(dbi, roDbi, clock, controlCacheDispatcher, nonEntityDao, internalCallContextFactory);
         final TagModelDao tag = new TagModelDao(clock.getUTCNow(), UUID.randomUUID(), UUID.randomUUID(), ObjectType.TAG);
 
         insertTag(tag);
diff --git a/util/src/test/java/org/killbill/billing/util/dao/TestEntityBaseDaoException.java b/util/src/test/java/org/killbill/billing/util/dao/TestEntityBaseDaoException.java
index 82d8eaa..1504340 100644
--- a/util/src/test/java/org/killbill/billing/util/dao/TestEntityBaseDaoException.java
+++ b/util/src/test/java/org/killbill/billing/util/dao/TestEntityBaseDaoException.java
@@ -1,6 +1,6 @@
 /*
- * Copyright 2014-2017 Groupon, Inc
- * Copyright 2014-2017 The Billing Project, LLC
+ * Copyright 2014-2018 Groupon, Inc
+ * Copyright 2014-2018 The Billing Project, LLC
  *
  * The Billing Project licenses this file to you under the Apache License, version 2.0
  * (the "License"); you may not use this file except in compliance with the
@@ -51,7 +51,7 @@ public class TestEntityBaseDaoException extends UtilTestSuiteWithEmbeddedDB {
 
     @Test(groups = "slow")
     public void testWithCreateException() throws Exception {
-        final EntitySqlDaoTransactionalJdbiWrapper entitySqlDaoTransactionalJdbiWrapper = new EntitySqlDaoTransactionalJdbiWrapper(dbi, clock, null, nonEntityDao, null);
+        final EntitySqlDaoTransactionalJdbiWrapper entitySqlDaoTransactionalJdbiWrapper = new EntitySqlDaoTransactionalJdbiWrapper(dbi, roDbi, clock, null, nonEntityDao, null);
         final TestEntityBaseDao test = new TestEntityBaseDao(entitySqlDaoTransactionalJdbiWrapper, KombuchaSqlDao.class);
 
         final KombuchaModelDao entity = new KombuchaModelDao() {
diff --git a/util/src/test/java/org/killbill/billing/util/UtilTestSuiteWithEmbeddedDB.java b/util/src/test/java/org/killbill/billing/util/UtilTestSuiteWithEmbeddedDB.java
index 0569958..f734d68 100644
--- a/util/src/test/java/org/killbill/billing/util/UtilTestSuiteWithEmbeddedDB.java
+++ b/util/src/test/java/org/killbill/billing/util/UtilTestSuiteWithEmbeddedDB.java
@@ -1,7 +1,7 @@
 /*
  * Copyright 2010-2014 Ning, Inc.
- * Copyright 2014-2017 Groupon, Inc
- * Copyright 2014-2017 The Billing Project, LLC
+ * Copyright 2014-2018 Groupon, Inc
+ * Copyright 2014-2018 The Billing Project, LLC
  *
  * The Billing Project licenses this file to you under the Apache License, version 2.0
  * (the "License"); you may not use this file except in compliance with the
@@ -44,7 +44,6 @@ import org.killbill.commons.locker.memory.MemoryGlobalLocker;
 import org.killbill.commons.locker.mysql.MySqlGlobalLocker;
 import org.killbill.commons.locker.postgresql.PostgreSQLGlobalLocker;
 import org.killbill.notificationq.api.NotificationQueueService;
-import org.skife.jdbi.v2.IDBI;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.testng.Assert;
@@ -87,8 +86,6 @@ public abstract class UtilTestSuiteWithEmbeddedDB extends GuicyKillbillTestSuite
     @Inject
     protected GlobalLocker locker;
     @Inject
-    protected IDBI idbi;
-    @Inject
     protected TestApiListener eventsListener;
     @Inject
     protected SecurityApi securityApi;