Set - 2

Question 1 :

How do I learn what codesets are available in Oracle?

Answer :

To find out what codesets you currently have available in Oracle, execute the following SQL query from SQLPlus at the command line:

SQL> SELECT value FROM v$nls_valid_values WHERE parameter='CHARACTERSET';

The response lists of all codesets currently installed on your system. This listing will look something like the following shortened list:
VALUE
---------------
US7ASCII
WE8DEC
WE8HP
US8PC437
WE8EBCDIC37
WE8EBCDIC500
WE8EBCDIC285
...

If you want to constrain the value in the query to a specific codeset you are searching for, you might use a SQL query like the following:
SQL> SELECT value FROM v$nls_valid_values
WHERE parameter='CHARACTERSET' and VALUE='AL24UTFFSS';

This would produce the following response if the codeset is installed:

VALUE
-------------------
AL24UTFFSS

You can use Oracle's installation tools to install additional codesets. Contact Oracle for more information.


Question 2 :

Why do I get an error while trying to retrieve the text for ORA-12705?

Answer :

This error occurs when you have not set the ORACLE_home environment variable properly — a common mistake. In order to use WebLogic jDriver for Oracle, the Oracle client software needs to be installed and ORACLE_home must be set.
You may also see this error message if you try to use WebLogic jDriver for Oracle's internationalization capabilities with a language/codeset combination that is not installed on your system. If you get the ORA-12705 error with the correct error text, then either you have set NLS_LANG improperly, or you do not have the right codesets installed on your system.


Question 3 :

Why do I run out of resources during updates with Oracle's database link?

Answer :

When you use Oracle's database link to update your database, you may get error "maximum number of temporary table locks exceeded" even if you close your result sets and statements when you finish.
The database link is an object in the local database that allows you to access tables, views, and such in a remote database. The database link is controlled by the Oracle server, so the driver has no control over its use of resources. The link appears to perform the commit (since other processes could see the records that were being created), but it doesn't free any resources until the connection is closed. The solution is to remove the database link and use the JDBC driver to do your selects, inserts, and updates.


Question 4 :

How do I prevent errors when running t3dbping?

Answer :

When you are testing your Oracle database connections under UNIX, you can run SQL*PLUS and can successfully ping the database using utils.dbping. However, when you use the multitier utils.t3dbping utility, you receive an ORA-12154 error message.

First, make sure that your ORACLE_home environment variable is correctly set to point to your Oracle installation. This variable must be set in the environment where the WebLogic server is running.

In the C-shell issue the following command:
$ setenv ORACLE_home path

where path is the path to your Oracle installation.
In the Bourne shell, issue the following commands:
$ ORACLE_home=path
$ export ORACLE_home


Question 5 :

Where path is the path to your Oracle installation.

Answer :

When you ping your database using the two-tier utils.dbping utility, the JDBC driver loads the database client library and establishes the connection to the database. When you use the multitier utils.t3dbping utility, the WebLogic Server loads a two-tier driver and uses it to establish a database connection. In both cases, the same method is used to connect to the database. SQL*PLUS works because it doesn't require ORACLE_home to find the client libraries.

If you are still experiencing problems, try this:
1. Open a command shell.
2. Run the two-tier version of utils.dbping in this shell.
3. Start WebLogic in this shell from the command line:
$ java -ms32m -mx32m weblogic.server
4. Open a second command shell.
5. Run the utils.t3dbping in the second shell against the server running in the first command shell.
If this procedure doesn't work, please send the output from these commands to WebLogic technical support.


Question 6 :

Why does executing the PreparedStatement class cause a "TRUNC fails: ORA-00932: inconsistent datatypes" error?

Answer :

According to Oracle Metalink Bug Database Doc ID: 144784.1, in the absence of explicit data typecasting, OCI assumes that a bind variable is a CHAR data type. If the SQL statement intends to use the bind variable as a DATE data type, but OCI thought it was a CHAR, the SQL parser will have a conflict in data types. The fix is to explicitly use data conversion functions to convert the bind variables in the problem queries. For example, a select string of
String st = "select count(*) from simple_table where
TRUNC(mydate) = TRUNC(?)";

should be changed to:
String st = "select count(*) from simple_table where
TRUNC(mydate) = TRUNC(TO_DATE(?))";


Question 7 :

Why am I getting an "ORA-01000: maximum open cursors exceeded" error, even though I closed all ResultSet, Statement, and Connection objects?

Answer :

This is an Oracle issue. According to Oracle's documentation, dynamic cursors can remain open from run to run in a session and are not closeable when a procedure closes. To work around this issue, you can increase the number of open cursors allowed in the database or you can reset the connection pool (close and reopen database connections in the connection pool).
To reset the connection pool, you can untarget and retarget the connection pool using the Administration Console. You can also use the reset() method through the JMX API or the RESET_POOL command on the WebLogic Server command line interface.


Question 8 :

Are there C/C++ interfaces to WLS JMS?

Answer :

No, this is not supported.
* Write your own interfaces using JNI.
* Setup a Servlet that your C/C++ client calls to generate a JMS message. You should spawn multiple threads in C++ and use multiple posts to pass messages via http.


Question 9 :

How do I start WLS and configure JMS?

Answer :

On Windows, start WLS 6.X by selecting Start -< Programs -< BEA WebLogic E-Business Platform -< WebLogic Server 6.X -< Start Default Server and enter the administrator password.
On Windows, to configure JMS, start the console by selecting Start -< Programs -< BEA WebLogic E-Business Platform -< WebLogic Server 6.X -< Start Default Console.
1. In the console tree view on the left, select JMS.
2. If you want persistent messages, first create a Store - Select Stores. In the window on the right, Select Create a new JMSFile Store for a file store, give it a name, give it a directory, select create. If you want a JDBCStore, you first need to create a JDBC connection pool by selecting JDBC in the tree view, Connection Pools, create a new JDBC Connection Pool. Select Targets, select a Target server, select the arrow that points to the right and select Apply. Then go back to Stores, Create a new JMSJDBCStore.
3. If you want to use a template, first create a Template - Select Templates. You need a template to create temporary queues. Select Create a new JMS Template, give it a name, select create, then you can move to the Thresholds &Quotas tab or the Override tab. Select Apply when done with your changes.
4. Select Servers. Select Create a new JMSServer, give it a name, select a Store if you created one, select a template if you created one, Select Create. Now you can move to the other tabs, make changes, select Apply. In particular, you must select Targets, select a Target server, select the arrow that points to the right, and select Apply. This is the server on which JMS will boot.
5. Create Destinations - from the tree view in the left panel, select the + in front of JMS, select the + in front of Servers, select the + in front of your server, select Destinations, Select Create a new JMSQueue or Create a new JMSTopic, fill in the first page and Select Create, then you can select, fill in, and Apply other tabs.
6. Create Connection Factories - on left tree view, open JMS. Select Connection Factory. Select Create a new JMS Connection Factory on the right panel. Type in the name and JNDI name. Select Create (lower right hand corner). Select the Targets tab. Select the name of the server on which you want to deploy the connection factory. Select the arrow pointing to the right - the server moves to chosen. Then select Apply (lower right hand corner).


Question 10 :

How do I configure JMS security?

Answer :

The correct way to set up security for JMS is to go to the console, select ACLs in the tree view, then create some access control lists.
1. Set the ACL name which should be weblogic.jms.queue.QUEUENAME or weblogic.jms.topic.TOPICNAME.
2. Select Create.
3. Enter the New Permission of send or receive.
4. Select Create.
5. Enter a comma separated list of users or groups.
6. Select Grant Permission.
7. Select "saved to the realm implementation" to save your changes.
8. Select Yes.
This will update the fileRealm.properties file with lines that look like the following:
acl.send.weblogic.jms.queue.TestQueue1=user1
acl.receive.weblogic.jms.queue.TestQueue1=user1
If you don't have an ACL for a queue or topic, security is wide open.
There are also ACL's for accessing the JNDI context; the JNDI context is a requirement for initially accessing JMS. See the JNDI documentation.


Question 11 :

Can I still use the default connection factories supported in WebLogic Release 5.1?

Answer :

Yes. The following two names for the default connection factories have been deprecated:

javax.jms.QueueConnectionFactory
javax.jms.TopicConnectionFactory.

However, these connection factories are still defined and usable in this release for backwards compatibility.
WebLogic JMS 6.1 defines one connection factory, by default:
weblogic.jms.ConnectionFactory
You have to Enable the JMS default connection factories. Go to the console->your server->tuning->click on the check box Enable Default JMS Connection Factories.
You can also specify user-defined connection factories using the Administration Console.


Question 12 :

Why does JMSSession.createTopic or JMSSession.createQueue fail to create a destination in WLS JMS 6.1 (it worked in 5.1)?

Answer :

In WLS 5.1 createTopic() or createQueue() creates the destination permanently in the database if it doesn't already exist, but does not modify the weblogic.properties file.
According to the JavaSoft JMS specification version 1.0.2 regarding createQueue() and createTopic(), they are not for creating destinations dynamically. They are used to retrieve the destination referenced by using a string name instead of using JNDI lookup. The destination has to be in your config.xml file first. This change is documented in WLS 6.0 since it behaves differently than the previous release. You can use the WLS JMS helper class (weblogic.jms.extensions.JMSHelper) or the console to create destinations at the run time (note that there was a bug in 6.0 that caused a problem when the server restarted; this is fixed in Service Pack 1). These mechanisms create the destination and also modify the configuration file.
For more information on the JMSHelper classes, see the subsection called Creating Destinations Dynamically in Programming WebLogic JMS.
The following program creates a Topic.

import java.io.*;
import java.util.Hashtable;
import javax.jms.*;
import javax.naming.*;
import weblogic.jms.extensions.JMSHelper;

class t {
public final static String
JNDI_FACTORY="weblogic.jndi.WLInitialContextFactory";
public final static String JMS_SERVER_NAME="TestJMSServer";
public final static String DEST_JNDI_PREFIX="javax.destination.";

static public void main(String [] args) throws Exception {
try {
Hashtable env = new Hashtable();
env.put(Context.INITIAL_CONTEXT_FACTORY, JNDI_FACTORY);
env.put(Context.PROVIDER_URL, "t3://localhost:7001");
Context ctx = new InitialContext(env);
String topicName = "JMSHelperTestQueue01";
String topicJNDI = DEST_JNDI_PREFIX + topicName;
System.out.println("topic name=" + topicName + ", jndi=" + topicJNDI);
JMSHelper.createPermanentTopicAsync(ctx, JMS_SERVER_NAME, topicName,topicJNDI);
} catch (JMSException e) {
e.printStackTrace();
}
}
}


Question 13 :

How do I programmatically get a list of Queues or Topics?

Answer :

The following program uses Mbeans:
import weblogic.management.*;
import weblogic.management.configuration.*;

InitialContext ic = new InitialContext();
MBeanhome home = (MBeanhome)ic.lookup(MBeanhome.ADMIN_JNDI_NAME);
for(Iterator i = o.getMBeansByType("JMSTopic").iterator();
i.hasNext(); ){
WebLogicMBean wmb = (WebLogicMBean)i.next();
System.out.println("topic name found: " + wmb.getName());
}

for(Iterator i = o.getMBeansByType("JMSQueue").iterator();
i.hasNext(); ){
WebLogicMBean wmb = (WebLogicMBean)i.next();
System.out.println("queue name found: " + wmb.getName());
}


Question 14 :

How do I use a temporary destination?

Answer :

You must create a template on every JMSServer where you want to be able to create temporary destinations. You can specify multiple JMSServer entries to support TemporaryTemplate and the system will load balance among those JMS servers to setup the temporary destination. See How do I start WLS and configure JMS? for a description about how to configure JMS. The resulting template definition looks something like the following:



The JMSServer is defined something like:



After the template name, you can set any queue/topic attribute you want in the template (not including a JNDI name or topic multicast settings). The template is at the outer most level; that is, it should not be nested in your .

Temporary destinations can only be consumed by the creating connection. Using topics, you create your temporary topic and subscribe to that temporary topic. If you want someone to publish to that temporary topic, you need to tell that someone what your topic is. You can send them a message and include your temporary topic in the JMSReplyTo field. The creator of the TemporaryTopic and the subscriber must be one in the same.

import javax.jms.TopicSession;
TemporaryTopic myTopic = mySession.createTemporaryTopic();
TopicSubscriber = mySession.createSubscriber(myTopic);

Temporary topics do not get names and cannot be subscribed to by other connections. When you create a temporary topic, the JMS provider returns a javax.jms.Topic. You then need to advertise that topic to other parties (those who want to publish to the topic), putting it in your JMSReplyTo field so that they can respond. In general, no one else can subscribe to the topic. You advertise the topic any way you want. Topics are serializable (or, in our case, externalizable), which allows you to pass them around in RMI calls, through a file, binding it to a name in JNDI, etc. In short, create the topic at the subscriber side and advertise so that others can publish. You can get multiple subscribers on the same connection and get concurrent processing using multiple sessions.


Question 15 :

Can two JMS servers share the same persistent store?

Answer :

No. Each JMS server must have its own unique persistent store. Two file-based JMS persistent stores may share the same directory, but their messages will be stored in different files. In this case, the filenames will contain different prefixes.
Two JDBC-based JMS persistent stores may share the same database, but they must be configured to use a different Prefix Name which will be prepended to the database tables. For more information on configuring the JDBC Prefix Name, see "JMS JDBC Stores" in the Administration Console Online Help. If they are configured with the same Prefix Name, persistent messages will be corrupted and/or lost.


Question 16 :

Which types of JDBC databases does WebLogic JMS support?

Answer :

The JMS database can be any database that is accessible through a JDBC driver. WebLogic supports and provides JDBC drivers for the following databases:
* Cloudscape
* Informix
* Microsoft SQL (MSSQL) Server (Versions 6.5 and 7)
* Oracle (Version 8.1.6)
* Sybase (Version 12)


Question 17 :

How do I use a third-party JDBC driver with JMS?

Answer :

If your JDBC driver is not included in the list of drivers in the question about JDBC databases supported by WebLogic JMS, then the tables required by JMS must be created manually.

Note: WebLogic Server only guarantees support for the JDBC drivers included in the previous list. Support for any other JDBC driver is not guaranteed.

The .ddl files located in the weblogic/jms/ddl directory of the weblogic.jar file may be used as templates. Use the jar utility supplied with the JDK to extract them to the weblogic/jms/ddl directory using the following command:

jar xf weblogic.jar weblogic/jms/ddl

Note: If you omit the second parameter (weblogic/jms/ddl), the entire jar file is extracted.
Follow the procedures in JDBC Database Utility in Programming WebLogic JMS to manually create the database tables for the JDBC store.
Another option is to consider using a file store instead of a JDBC store. File stores are easier to configure and may provide significantly better performance.


Question 18 :

How do I use persistence?

Answer :

Use the following guidelines:
1. Make sure the JMSServer you are using has a store configured. The JMSServer configuration entry in the config.xml file should contain a line of the form

Store=""
Note that if JMS boots without a store configured, it is assumed the customer did not want one, and persistent messages are silently downgraded to non-persistent (as specified for JMS 1.0.2).
2. Make sure you are not using "Message.setJMSDeliveryMode". This is overwritten, as it is a vendor-only method.
3. Make sure you are calling either:
QueueSender.send(msg, deliveryMode, ...)
-- or --
QueueSender.setDeliveryMode(deliveryMode)
-- or --
set the DefaultDeliveryMode mode on connection factory in the config.xml file to persistent (the QueueSender.setDeliver/send overrides this value). Similarly, for topics, you would set this via the TopicPublisher.
4. Make sure you don't have "DeliveryModeOverride" set to Non-Persistent on the Destination in the config.xml file.
5. If you are using pub/sub, only durable subscriptions persist messages. Non-durable subscriptions have no need to persist messages, as by definition they only exist for the life of the server.
6. If you are using JDBC, the JDBC tables, JMSSTATE and JMSSTORE, are created automatically when the JMS server boots. The DDL files used to create the tables are stored in weblogic.jar in weblogic/jms/ddl. The example configuration below shows a JDBC store for Oracle (client version 8.1.7 or later is needed to run with WLS 6.1 on JDK 1.3). To manually create the tables (also deleting any existing tables), run java utils.Schema as described in the previous question.
See the question, "How do I start WLS and configure JMS?" for a description of how to configure JMS.
Here is a sample config.xml file resulting from configuring JMS. It should look similar to yours. If you want JMS to use a file store instead of a database, just change JDBCStore to FileStore in the JMSServer section.




Targets="myserver" Store="JDBCStore">







The following is a sample class that sends
a Topic message on construction:

import javax.naming.*;
import javax.jms.*;
import java.util.Hashtable;

public class t

{
public final static String DESTINATION="jms.topic.TestTopic1";

private TopicConnectionFactory connectionFactory;
private TopicConnection connection;
private TopicSession session;
private TopicPublisher producer;
private TextMessage message;
private Topic destination;

public t()
{
try {
Hashtable env = new Hashtable();
env.put(Context.INITIAL_CONTEXT_FACTORY,
"weblogic.jndi.WLInitialContextFactory");
env.put(Context.PROVIDER_URL, "t3://localhost:7001");
InitialContext ctx = new InitialContext(env);
destination = (Topic) ctx.lookup(DESTINATION);
connectionFactory = (TopicConnectionFactory)
ctx.lookup("javax.jms.TopicConnectionFactory");
connection = (TopicConnection)
connectionFactory.createTopicConnection();
session = (TopicSession) connection.createTopicSession(false,

Session.AUTO_ACKNOWLEDGE);
producer = (TopicPublisher) session.createPublisher(destination);
producer.setDeliveryMode(DeliveryMode.PERSISTENT);
message = (TextMessage) session.createTextMessage();
message.setText("hello world");
producer.publish(message);
} catch (Exception e) {
}
}
}


Question 19 :

How does a file store compare with a JDBC store?

Answer :

The following are some similarities and differences between file stores and JDBC stores:
* Both have the same transaction semantics, including rolling back transactions (e.g., received messages are put back on the queue).
* Both have the same application interface (no difference in application code).
* The file store should be much faster.
* JDBC may make it easier to handle failure recovery since the JDBC interface can access the database from any client machine; with the file store, the disk must be shared or migrated.
* File store reliability is limited to reliability of disk and O/S; run it on Veritas or a RAID 5 system. Database reliability may be higher.
* File stores will require more memory, but perhaps not significantly more; it depends on how fragmented the file store gets, if the application works roughly
* FIFO it shouldn't get very fragmented at all.
* File stores generate no additional network traffic, database stores do if the database server is on a different JVM or machine.


Question 20 :

How do the WLS JMS 6.1 server/destination message maximum and threshold values work?

Answer :

The byte and message maximum values are quotas - not flow control. Message quotas prevent a WebLogic JMS server from filling up with messages and possibly running out of memory, causing unexpected results. When you reach your quota, JMS prevents further sends with a ResourceAllocationException (rather than blocking). You can set quotas on individual destinations or on a server as a whole.
The thresholds are also not flow control - though they would be better suited to that application than the quotas. The thresholds are simply settings that when exceeded cause a message to be logged to the console to let you know that you are falling behind.
Note that the messages maximum setting on a connection factory is not a quota. This specifies the maximum numbers of outstanding messages that can exist after they have been pushed from the server but before an asynchronous consumer has seen them; it defaults to a value of 10.


Question 21 :

How do I configure JDBC so that the JMS JDBC Store recovers automatically?

Answer :

Several customers have reported a problem where they are using a JDBC store, the DBMS goes down and back up, but JMS can no longer use the store until WLS is shutdown and restarted. You can get around this problem by configuring the following attributes on the JDBC Connection Pool associated with the JMSJDBCStore:

TestConnectionsOnReserve="true"\
TestTableName="[[[catalog.]schema.]prefix]JMSState"

If they are not set, then if the JDBC resource goes down and comes back up, JMS cannot re-use the connection pool until WLS is shutdown and restarted. This has been tested against WLS 6.0 SP02 and WLS 6.1.


Question 22 :

Does WebLogic JMS support clustering?

Answer :

WebLogic JMS supports cluster-wide, transparent access to destinations from any server in the cluster. A system administrator can establish cluster-wide, transparent access to destinations from any server in the cluster by configuring multiple connection factories and using targets to assign them to WebLogic Servers. Each connection factory can be deployed on multiple WebLogic Servers.

The application uses the Java Naming and Directory Interface (JNDI) to look up a connection factory and create a connection to establish communication with a JMS server. Each JMS server handles requests for a set of destinations. Requests for destinations not handled by a JMS server are forwarded to the appropriate server.

You can configure multiple JMS servers on the various nodes in the cluster as long as you give them different names. You can assign destinations to the various JMS servers.

One problem to be aware of is the propagation delay in replicating entries in JNDI. If you have an MDB deployed on one node but reference a destination on another node, the deployment may fail with a javax.naming.NamingException exception. The problem occurs because the server is not synced up to the JNDI from the remote server (JMS server) yet, so the JNDI lookup of destination as part of MDB deployment will fail. One workaround is for each MDB to reference a local destination. Another approach is deploy the MDBs after the server boots (plus a delay for JNDI propagation). To get around losing messages before the MDB is deployed, use durable subscribers. This problem is fixed for MDBs in WLS 6.1, where the MDB will be deployed and reconnection will be retried until the destination is available. Note that this is still a problem for EJBs in general that try to reference a non-local JMS destination.


Question 23 :

How do I do HTTP tunneling?

Answer :

If you want to use HTTP tunneling (wrap every message in HTTP to get through a firewall), you need to add TunnelingEnabled="true" into your &lr;ver> definition in the config.xml file or check the appropriate box on the console. Then use a URL like http://localhost:7001 instead of t3://localhost:7001 for Context.PROVIDER_URL when getting your InitialContext. If you want HTTP tunneling with SSL, use https://localhost:7002 (where https uses HTTP tunneling with SSL and 7002 is the secure port that you configured). You will pay a performance penalty for doing this, so only use tunneling it if you really need to (i.e., need to go through a firewall).


Question 24 :

Why is my JMS work not part of a user transaction (i.e., called within a transaction but not rolled back appropriately)? How do I track down transaction problems?

Answer :

Usually this problem is caused by explicitly using a transacted session which ignores the external, global transaction by design (JMS spec requirement). A transacted JMS session always has its own inner transaction. It is not affected by any transaction context that the caller may have.

It may also be caused by using a connection factory that is configured with "UserTransactionsEnabled" set to false.
1. You can check if the current thread is in a transaction by adding these two import lines:
import javax.transaction.*
import weblogic.transaction.*;

and adding the following lines (i.e., just after the begin and just before every operation).

Transaction tran = TxHelper.getTransaction();
System.out.println(tran);
System.out.println(TxHelper.status2String(tran.getStatus()));

This should give a clear idea of when new transactions are starting and when infection is occurring.
2. Ensure that the thread sending the JMS message is infected with a transaction. Check that the code is not using a transacted session by setting the first parameter of createQueueSession or createTopicSession to false. Note that creating the connection and/or session is orthogonal to the transaction. You can begin your transaction before or after. You need only start the transaction before you send or receive messages.
3. Check that the UserTransactionsEnabled flag is explicitly set to true for the connection factory in the config.xml file since the default for user-configured connection factories for this value is false. If you are using one of the pre-configured connection factories they are set as follows:
weblogic.jms.ConnectionFactory disables user transactions so
don't use this one for the case where user transactions are
desired;

javax.jms.QueueConnectionFactory and
javax.jms.TopicConnectionFactory enable user transactions.
4. You can trace JTA operations by starting the server with this additional property:
-Dweblogic.Debug.DebugJMSXA=true
You should see trace statements like these in the log:
XA ! XA(3163720,487900)
This can be used to ensure that JMS is infected with the transaction.


Question 25 :

How can an application do a JMS operation and have it succeed, independent of the result of the transaction?

Answer :

Basically, the JMS operation must be done using a transacted session or the transaction must be suspended/disabled as follows (pick one or more of the following).

1. Suspend the current transaction prior to making the JMS call and resume it after completing it. The code looks something like this:
import javax.transaction.Transaction;
import javax.transaction.TransactionManager;
TransactionManager tranManager=
TxHelper.getTransactionManager();
Transaction saveTx = null;
try {
saveTx = tranManager.suspend();
... do JMS work, it will not participate in transaction
} finally {
// must always resume suspended transactions!
if (saveTx != null) tranManager.resume(saveTx);
}
2. Use a transacted session by specifying true for the first parameter to createQueueSession or createTopicSession.
3. Use a connection factory with user transactions disabled. That is, check that the UserTransactionsEnabled flag is explicitly set to false for the connection factory in the config.xml file or use the default for a user-configured connection factory for this value which is false. The pre-configured connection factory weblogic.jms.ConnectionFactory disables user transactions.

A transacted JMS session always has its own inner transaction. It is not affected by any transaction context that the caller may have. A non-transacted JMS session is more complicated. If you use the WLS 6.1 default factory weblogic.jms.ConnectionFactory, the session does not participate in a user transaction because the UserTransactionsEnabled flag is set to "False". If you use the deprecated default factory javax.jms.QueueConnectionFactory or javax.jms.TopicConnectionFactory or you define your own factory and set the UserTransactionsEnabled flag to "True", the JMS session participates in the outer transaction, if one exists and the JMS session is not transacted.


Question 26 :

What happens if acknowledge() is called within a transaction?

Answer :

As per the JMS specification, when you are in a transaction, the acknowledgeMode is ignored. If acknowledge() is called within a transaction, it is ignored.


Question 27 :

Is it possible to set aside a message and acknowledge it later?

Answer :

There are no special primitives for doing this. Here are two possible solutions.
One approach is to use multiple sessions as in the following:
while (true) {
Create a session, subscribe to one message on durable
subscription
Close session
Save session reference in memory
To acknowledge the message, find the session reference and call
acknowledge() on it.
}

Another solution is to use transactions and suspend the work as follows:
start transaction
while(true) {
message = receive();
if (message is one that I can handle)
process the message
commit
} else {
suspend transaction
put transaction aside with message
start transaction
}
}

To "acknowledge" the message:
resume user transaction
commit

To "recover" the message:
resume user transaction
rollback

Each time you suspend, you need to push the transaction onto a stack or list possibly with the message so you can process it or roll it back later. This solution is high overhead in that there can be a large build up of outstanding transactions. Note that transactions have timeouts and it may rollback on its own, which means you can get the message again (in a different transaction). Note also that there are some practical limits on the number of transactions you should leave outstanding. The default limit is something like 10000. Eventually you want to go back to your stack/list and commit/rollback the transactions. Note that transaction references (javax.transaction.Transaction) are not Serializable.


Question 28 :

How should I use sorted queues?

Answer :

Destination keys are used to define the sort order for a specific destination. Destination keys can be message header or property fields. For a list of valid message header and property fields, refer to the Programming WebLogic JMS.
Queues can be sorted in ascending or descending order based on the destination key. A destination is considered to be first-in-first-out if a destination key is defined as ascending for the JMSMessageID message header field, and last-in-first-out if defined as descending. The key defined for the JMSMessageID header field, if specified, must be the last key defined in the list of keys.
You can define multiple destination keys to sort a destination.


Question 29 :

How does sorting on message priority work?

Answer :

First, you need to add a key to the destination (by default, they are not sorted), choosing JMSPriority as the key. If you want 0 to be your highest priority, make the key ascending. If you want 9 to be the highest priority, make the key descending.
Second, the priority must be set using either the producer or on the send, not the message.
Third, the priority sorting only comes into play if there are multiple messages waiting on the queue. If the receiver is always caught up with the sender, then the messages will be processed in the order in which they come in.


Question 30 :

How do I get a thread dump to help track down a problem?

Answer :

Ways to get a thread dump:
* Try running this from the command line (after running the setEnv script in /bea/wlserver6.1/config/mydomain/):

java weblogic.Admin -url t3://localhost:7001 THREAD_DUMP

* On Windows, from the console window, enter Ctrl+Break.
* On UNIX, signal the server using kill -3.