मुझे लगता है कि मैं एक समाधान के करीब हूं, लेकिन मैं इसके साथ पूरी तरह से खुश नहीं हूं। मैं आने के लिए एक बेहतर जवाब के लिए प्यार करता हूँ।
संपादित: पता चला है यह, नहीं काफी काम करता है वसंत के रूप में या हाइबरनेट केवल वर्तमान किरायेदार पहचानकर्ता रिसोल्वर एक बार फोन करने के लिए, हर बार के लिए एक @Transactional विधि
यह CurrentTenantIdentifierResolver
कार्यान्वयन में बदला जाता है कहा जाता है नहीं दिखाई देता है वर्तमान उपयोगकर्ता को (यदि यह सेट किया गया है) को न केवल अपने वर्तमान किरायेदार आईडी (इसे सेट करने के तरीके को समझने के लिए कार्यान्वयन करने के लिए) को देखने के लिए ... इसे एक थ्रेड स्थानीय चर को देखने की आवश्यकता है ताकि यह देखने के लिए कि ओवरराइड निर्धारित किया गया है।
इस दृष्टिकोण का उपयोग करके, मैं अस्थायी रूप से किरायेदार सेट कर सकता हूं ... निर्दिष्ट मेरे बहु किरायेदारी लेनदेन प्रबंधक के साथ एक सेवा विधि को कॉल करें और फिर डेटा प्राप्त करें।
मेरे टेस्ट सेवा:
@Service
public class TestService
{
@Transactional(transactionManager = "sharedTxMgr")
public void doSomeGets()
{
List<String> tenants = getListSomehow();
try(MultitenancyTemporaryOverride tempOverride = new MultitenancyTemporaryOverride())
{
for(String tenant : tenants)
{
tempOverride.setCurrentTenant(tenant);
doTenantSpecificWork();
}
}
catch (Exception e)
{
logger.error(e);
}
}
@Transactional(transactionManager = "tenantSpecificTxMgr")
public void doTenantSpecificWork()
{
//do some work here, which only applies to the tenant
}
}
मेरी कक्षा कि ThreadLocal की स्थापना लपेटता, AutoCloseable लागू करने में मदद करने के लिए सुनिश्चित चर बनाने
public class MultitenancyTemporaryOverride implements AutoCloseable
{
static final ThreadLocal<String> tenantOverride = new ThreadLocal<>();
public void setCurrentTenant(String tenantId)
{
tenantOverride.set(tenantId);
}
public String getCurrentTenant()
{
return tenantOverride.get();
}
@Override
public void close() throws Exception
{
tenantOverride.remove();
}
}
मेरे किरायेदार समाधानकर्ता कार्यान्वयन कि धागा स्थानीय
का उपयोग करता है ऊपर साफ किया जाता है
public class CurrentTenantIdentifierResolverImpl implements CurrentTenantIdentifierResolver
{
@Override
public String resolveCurrentTenantIdentifier()
{
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
logger.debug(ToStringBuilder.reflectionToString(authentication));
String database = "shared";
if (authentication != null && authentication.getPrincipal() instanceof MyUser)
{
MyUser user = (MyUser) authentication.getPrincipal();
database = user.getTenantId();
}
String temporaryOverride = MultitenancyTemporaryOverride.tenantOverride.get();
if(temporaryOverride != null)
{
database = temporaryOverride;
}
return database;
}
स्रोत
2016-04-11 16:15:43
जब आप कहते हैं कि "कॉन्फ़िगरेशन पढ़ें" क्या आपका मतलब प्रत्येक किरायेदार के डेटाबेस में एक तालिका है? आप इस ब्लॉग [पोस्ट] (http://anakiou.blogspot.my/2015/08/multi-tenant-plplication-with-spring.html) पर एक नज़र डालना चाहेंगे जो आपको कुछ विचार दे सकता है। यदि आपके पास डेटा स्रोतों की एक सूची है, तो मुझे लगता है कि आपका एप्लिकेशन शुरू होने पर उन्हें लूप करना मुश्किल नहीं होगा। उदाहरण के रूप में "कॉन्फ़िगरेशन टेबल" का उपयोग करके – Mustafa
खराब विकल्प हो सकता है, क्योंकि यह चीजों को भ्रमित कर सकता है। मेरे पास वास्तव में कुछ चीजें हैं जिन्हें विभिन्न किरायेदारों के लिए विभिन्न कारणों से पढ़ना होगा। आपके द्वारा प्रदान किया गया ब्लॉग पोस्ट बताता है कि डेटा स्रोतों को आगे बढ़ाना, जो कुछ मुझे नहीं पता। –
बहु-किरायेदार द्वारा क्या आपका मतलब है 'उपयोगकर्ता' नामक एक टेबल होने जैसा कुछ डेटाबेस डेटाबेस पर 'dropbox_db',' google_drive_db', 'sky_drive_db' आदि जैसे कई डेटाबेस में दिखाई देता है? – Saheed