Java EE में JTA डिफ़ॉल्ट और टाइमआउट

लेखक
Damian
Terlecki
8 मिनट पढ़ें
जेईई

आपका सिस्टम वर्षों तक बिना किसी बाधा के काम कर सकता है, लेकिन फिर एक दिन, JTA (जावा ट्रांजैक्शन एपीआई) टाइमआउट दिखाई देने लगते हैं:

[WebLogic] Transaction Rolledback.: weblogic.transaction.internal.TimedOutException: Transaction timed out after 301 seconds
(...) No further JDBC access is allowed within this transaction....

[WebSphere] TimeoutManage I WTRN0006W: Transaction (...) has timed out after 120 seconds.

[JBoss/WildFly] javax.transaction.RollbackException: ARJUNA016102: The transaction is not active!

हालांकि कुछ उपयोग के मामलों के लिए विशिष्ट, JTA लेनदेन टाइमआउट की घटना असामान्य नहीं है और उत्पादन में हो सकती है। विशेष रूप से, जब डेटा की मात्रा शुरू में परिभाषित सीमाओं की तुलना में बहुत बढ़ जाती है। शायद, आपने अभी-अभी एक अलग एप्लिकेशन सर्वर पर स्विच किया है?

स्प्रिंग में यह बच्चों का खेल है। एक क्लास/इंटरफ़ेस/मेथड स्तर पर हम इसे @org.springframework.transaction.annotation.Transactional(timeout = SECONDS) एनोटेशन का उपयोग करके कॉन्फ़िगर कर सकते हैं। यह समान है, चाहे हम कंटेनर द्वारा प्रदान किए गए JTA, एम्बेडेड एक, या सिर्फ एक सादे डेटा स्रोत टीएम का उपयोग करना चाहते हैं।

हालांकि, JavaEE की दुनिया में, यह इतना सीधा नहीं है। समकक्ष javax.transaction.Transactional इस समय टाइमआउट को कॉन्फ़िगर करने के लिए एक एपीआई को उजागर नहीं करता है, यह वृद्धि खुली छोड़ दी गई है। इस प्रकार, डिफ़ॉल्ट टाइमआउट, साथ ही इसे प्रति कार्य इकाई कॉन्फ़िगर करने की क्षमता, कार्यान्वयनकर्ताओं के निर्णय पर छोड़ दी गई है।

उदाहरण और डिफ़ॉल्ट

आइए देखें कि यह JavaEE वातावरण में कैसे काम करता है। हम सबसे सरल सिंगलटन बीन को परिभाषित करेंगे जो एप्लिकेशन स्टार्टअप पर इंस्टेंटियेट किया जाएगा:

package mypackage;

import javax.annotation.PostConstruct;
import javax.ejb.Singleton;
import javax.ejb.Startup;

@Startup
@Singleton(name = "StartupBean")
public class StartupBean {
    @PostConstruct
    public void init() {
        System.out.println("Starting the initialization");
        try {
            Thread.sleep(31_000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("Finished initializing");
    }
}

शब्दबहुलता के लिए, इस बीन में एक प्रासंगिक एनोटेशन गायब है, जो है @TransactionManagement(TransactionManagementType.CONTAINER)। यह JavaEE से शुरू करने वाले लोगों के लिए सहज नहीं हो सकता है लेकिन:

यदि इस एनोटेशन का उपयोग नहीं किया जाता है, तो बीन को कंटेनर-प्रबंधित लेनदेन प्रबंधन माना जाता है।

इसके अलावा, मेथड स्तर पर, एक @TransactionAttribute(TransactionAttributeType.REQUIRED) एनोटेशन भी गायब है:

यदि TransactionAttribute एनोटेशन निर्दिष्ट नहीं है, और बीन कंटेनर-प्रबंधित लेनदेन सीमांकन का उपयोग करता है, तो REQUIRED लेनदेन विशेषता के शब्दार्थ को मान लिया जाता है।

नए बीन्स बनाते समय इन डिफ़ॉल्ट को याद रखना उचित है। अंत में, जब मैं इसे WebLogic 12.2 पर तैनात करता हूं, तो मुझे मिलता है:

weblogic.ejb.container.InternalException: Transaction marked rollback or not expected transaction status: 4

और WebLogic एप्लिकेशन को तैनात करने में असमर्थ है (यह STATE_NEW स्थिति में रहता है)। ऐसा इसलिए है क्योंकि @PostConstruct मेथड भी JTA लेनदेन द्वारा कवर किया गया है, जो इस मामले में, 30 सेकंड का डिफ़ॉल्ट टाइमआउट है।

JTA को अक्षम करने के लिए, हम या तो मेथड/क्लास स्तर पर @TransactionAttribute(TransactionAttributeType.NOT_SUPPORTED) का उपयोग कर सकते हैं या क्लास स्तर पर @TransactionManagement(TransactionManagementType.BEAN) एनोटेशन का उपयोग कर सकते हैं।

टाइमआउट

दूसरी ओर, यदि हमारे पास वास्तव में ऐसे मेथड में एक ट्रांजैक्शनल लॉजिक है (शायद @PostConstruct में नहीं), तो हम शायद स्प्रिंग की तरह ही टाइमआउट को कॉन्फ़िगर करने में रुचि लेंगे। इस मामले में, हमें विशेष JEE कंटेनर कार्यान्वयन के प्रलेखन से परामर्श करना होगा।

WebLogic के मामले में, हम WebLogic कंसोल के माध्यम से डोमेन स्तर पर टाइमआउट को कॉन्फ़िगर कर सकते हैं।

वेबलॉजिक कंसोल के डोमेन-स्तरीय JTA कॉन्फ़िगरेशन का स्क्रीनशॉट

यह आपके डोमेन इंस्टॉलेशन डायरेक्टरी के कॉन्फिग फ़ोल्डर में मिली config.xml फ़ाइल में कुछ प्रविष्टियाँ जोड़ता है:

<!--...-->
  </security-configuration>
  <jta>
    <timeout-seconds>31</timeout-seconds>
    <abandon-timeout-seconds>86400</abandon-timeout-seconds>
    <forget-heuristics>true</forget-heuristics>
    <before-completion-iteration-limit>10</before-completion-iteration-limit>
    <max-transactions>10000</max-transactions>
    <max-unique-name-statistics>1000</max-unique-name-statistics>
    <checkpoint-interval-seconds>300</checkpoint-interval-seconds>
    <parallel-xa-enabled>true</parallel-xa-enabled>
    <unregister-resource-grace-period>30</unregister-resource-grace-period>
    <two-phase-enabled>true</two-phase-enabled>
    <clusterwide-recovery-enabled>false</clusterwide-recovery-enabled>
    <tightly-coupled-transactions-enabled>false</tightly-coupled-transactions-enabled>
    <tlog-write-when-determiner-exists-enabled>false</tlog-write-when-determiner-exists-enabled>
  </jta>
<!--...-->

अधिक विशिष्ट (बीन-स्तरीय) कॉन्फ़िगरेशन weblogic-ejb-jar.xml डिस्क्रिप्टर के माध्यम से किया जा सकता है जिसे WAR के WEB-INF या JAR के META-INF डायरेक्टरी में रखा गया है। कॉन्फ़िगरेशन ejb-name के माध्यम से मेल खाता है जिसे बीन name एनोटेशन तत्व द्वारा भी परिभाषित किया गया है।

<?xml version = '1.0' encoding = 'UTF-8'?>
<weblogic-ejb-jar xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                  xsi:schemaLocation="http://www.bea.com/ns/weblogic/weblogic-ejb-jar http://www.bea.com/ns/weblogic/weblogic-ejb-jar/1.0/weblogic-ejb-jar.xsd"
                  xmlns="http://www.bea.com/ns/weblogic/weblogic-ejb-jar">
    <weblogic-enterprise-bean>
        <ejb-name>StartupBean</ejb-name>
        <transaction-descriptor>
            <trans-timeout-seconds>60</trans-timeout-seconds>
        </transaction-descriptor>
    </weblogic-enterprise-bean>
</weblogic-ejb-jar>

अन्य प्रदाताओं के लिए, यह भिन्न हो सकता है। नवीनतम Oracle Commerce Platform इंस्टॉलेशन गाइड में एक त्वरित जांच JBoss, WebLogic और WebSphere के लिए कुछ सामान्य अवलोकन देती है। JBoss/WildFly में स्प्रिंग के समान अतिरिक्त @org.jboss.ejb3.annotation.TransactionTimeout एनोटेशन है। WebLogic के समान, JBoss/Wildfly भी jboss-ejb3.xml डिस्क्रिप्टर में एक <tx:trans-timeout> कॉन्फ़िगरेशन तत्व प्रदान करता है। WebSphere में, दूसरी ओर, इस तत्व को <global-transaction> कहा जाता है और इसे ibm-ejb-jar-ext.xml डिस्क्रिप्टर में रखा जाता है।

अंत में, एक महीन-दानेदार नियंत्रण के लिए हम BMT (बीन प्रबंधित लेनदेन) पर स्विच कर सकते हैं। उस स्थिति में हम टाइमआउट सेट करने के लिए javax.transaction.TransactionManager.setTransactionTimeout(int seconds) या javax.transaction.UserTransaction.setTransactionTimeout(int seconds) विधियों का उपयोग करेंगे।

सारांश

इससे कुछ प्रमुख बातें निकलती हैं:

  • @Transactional API Java EE और स्प्रिंग के बीच भिन्न है;
  • EJB बीन्स में डिफ़ॉल्ट रूप से CMT (कंटेनर प्रबंधित लेनदेन) सक्षम होता है जब तक कि आप स्पष्ट रूप से अन्यथा घोषित न करें;
  • CMT टाइमआउट को नियंत्रित करना कार्यान्वयन-विशिष्ट है, सबसे अच्छा विचार कंटेनर प्रलेखन की जांच करना है।