| type=page |
| status=published |
| title=Tuning Your Application |
| next=tuning-glassfish.html |
| prev=overview.html |
| ~~~~~~ |
| |
| = Tuning Your Application |
| |
| [[GSPTG00004]][[abebe]] |
| |
| |
| [[tuning-your-application]] |
| == 2 Tuning Your Application |
| |
| This chapter provides information on tuning applications for maximum |
| performance. A complete guide to writing high performance Java and Java |
| EE applications is beyond the scope of this document. |
| |
| The following topics are addressed here: |
| |
| * link:#abebf[Java Programming Guidelines] |
| * link:#abebp[Java Server Page and Servlet Tuning] |
| * link:#abebw[EJB Performance Tuning] |
| |
| [[abebf]][[GSPTG00052]][[java-programming-guidelines]] |
| |
| === Java Programming Guidelines |
| |
| This section covers issues related to Java coding and performance. The |
| guidelines outlined are not specific to {productName}, but are |
| general rules that are useful in many situations. For a complete |
| discussion of Java coding best practices, see the |
| http://www.oracle.com/technetwork/java/javaee/blueprints/index.html[Java |
| Blueprints] |
| (`http://www.oracle.com/technetwork/java/javaee/blueprints/index.html`). |
| |
| The following topics are addressed here: |
| |
| * link:#abebg[Avoid Serialization and Deserialization] |
| * link:#abebh[Use `StringBuilder` to Concatenate Strings] |
| * link:#abebi[Assign null to Variables That Are No Longer Needed] |
| * link:#abebj[Declare Methods as final Only If Necessary] |
| * link:#abebk[Declare Constants as static final] |
| * link:#abebl[Avoid Finalizers] |
| * link:#abebm[Declare Method Arguments final] |
| * link:#abebn[Synchronize Only When Necessary] |
| * link:#abebo[Use DataHandlers for SOAP Attachments] |
| |
| [[abebg]][[GSPTG00161]][[avoid-serialization-and-deserialization]] |
| |
| ==== Avoid Serialization and Deserialization |
| |
| Serialization and deserialization of objects is a CPU-intensive |
| procedure and is likely to slow down your application. Use the |
| `transient` keyword to reduce the amount of data serialized. |
| Additionally, customized `readObject()` and `writeObject()` methods may |
| be beneficial in some cases. |
| |
| [[abebh]][[GSPTG00162]][[use-stringbuilder-to-concatenate-strings]] |
| |
| ==== Use `StringBuilder` to Concatenate Strings |
| |
| To improve performance, instead of using string concatenation, use |
| `StringBuilder.append()`. |
| |
| String objects are immutable - that is, they never change after |
| creation. For example, consider the following code: |
| |
| [source,java] |
| ---- |
| String str = "testing"; |
| str = str + "abc"; |
| str = str + "def"; |
| ---- |
| |
| The compiler translates this code as: |
| |
| [source,java] |
| ---- |
| String str = "testing"; |
| StringBuilder tmp = new StringBuilder(str); |
| tmp.append("abc"); |
| str = tmp.toString(); |
| StringBulder tmp = new StringBuilder(str); |
| tmp.append("def"); |
| str = tmp.toString(); |
| ---- |
| |
| This copying is inherently expensive and overusing it can reduce |
| performance significantly. You are far better off writing: |
| |
| [source,java] |
| ---- |
| StringBuilder tmp = new StringBuilder(16); |
| tmp.append("testing"); |
| tmp.append("abc"); |
| tmp.append("def"); |
| String str = tmp.toString(); |
| ---- |
| |
| [[abebi]][[GSPTG00163]][[assign-null-to-variables-that-are-no-longer-needed]] |
| |
| ==== Assign null to Variables That Are No Longer Needed |
| |
| Explicitly assigning a null value to variables that are no longer needed |
| helps the garbage collector to identify the parts of memory that can be |
| safely reclaimed. Although Java provides memory management, it does not |
| prevent memory leaks or using excessive amounts of memory. |
| |
| An application may induce memory leaks by not releasing object |
| references. Doing so prevents the Java garbage collector from reclaiming |
| those objects, and results in increasing amounts of memory being used. |
| Explicitly nullifying references to variables after their use allows the |
| garbage collector to reclaim memory. |
| |
| One way to detect memory leaks is to employ profiling tools and take |
| memory snapshots after each transaction. A leak-free application in |
| steady state will show a steady active heap memory after garbage |
| collections. |
| |
| [[abebj]][[GSPTG00164]][[declare-methods-as-final-only-if-necessary]] |
| |
| ==== Declare Methods as final Only If Necessary |
| |
| Modern optimizing dynamic compilers can perform inlining and other |
| inter-procedural optimizations, even if Java methods are not declared |
| `final`. Use the keyword `final` as it was originally intended: for |
| program architecture reasons and maintainability. |
| |
| Only if you are absolutely certain that a method must not be overridden, |
| use the `final` keyword. |
| |
| [[abebk]][[GSPTG00165]][[declare-constants-as-static-final]] |
| |
| ==== Declare Constants as static final |
| |
| The dynamic compiler can perform some constant folding optimizations |
| easily, when you declare constants as `static final` variables. |
| |
| [[abebl]][[GSPTG00166]][[avoid-finalizers]] |
| |
| ==== Avoid Finalizers |
| |
| Adding finalizers to code makes the garbage collector more expensive and |
| unpredictable. The virtual machine does not guarantee the time at which |
| finalizers are run. Finalizers may not always be executed, before the |
| program exits. Releasing critical resources in `finalize()` methods may |
| lead to unpredictable application behavior. |
| |
| [[abebm]][[GSPTG00167]][[declare-method-arguments-final]] |
| |
| ==== Declare Method Arguments final |
| |
| Declare method arguments `final` if they are not modified in the method. |
| In general, declare all variables `final` if they are not modified after |
| being initialized or set to some value. |
| |
| [[abebn]][[GSPTG00168]][[synchronize-only-when-necessary]] |
| |
| ==== Synchronize Only When Necessary |
| |
| Do not synchronize code blocks or methods unless synchronization is |
| required. Keep synchronized blocks or methods as short as possible to |
| avoid scalability bottlenecks. Use the Java Collections Framework for |
| unsynchronized data structures instead of more expensive alternatives |
| such as `java.util.HashTable`. |
| |
| [[abebo]][[GSPTG00169]][[use-datahandlers-for-soap-attachments]] |
| |
| ==== Use DataHandlers for SOAP Attachments |
| |
| Using a `javax.activation.DataHandler` for a SOAP attachment will |
| improve performance. |
| |
| JAX-RPC specifies: |
| |
| * A mapping of certain MIME types to Java types. |
| * Any MIME type is mappable to a `javax.activation.DataHandler` . |
| |
| As a result, send an attachment (`.gif` or XML document) as a SOAP |
| attachment to an RPC style web service by utilizing the Java type |
| mappings. When passing in any of the mandated Java type mappings |
| (appropriate for the attachment's MIME type) as an argument for the web |
| service, the JAX-RPC runtime handles these as SOAP attachments. |
| |
| For example, to send out an `image/gif` attachment, use |
| `java.awt.Image`, or create a `DataHandler` wrapper over your image. The |
| advantages of using the wrapper are: |
| |
| * Reduced coding: You can reuse generic attachment code to handle the |
| attachments because the `DataHandler` determines the content type of the |
| contained data automatically. This feature is especially useful when |
| using a document style service. Since the content is known at runtime, |
| there is no need to make calls to |
| `attachment.setContent(stringContent, "image/gif")`, for example. |
| * Improved Performance: Informal tests have shown that using |
| `DataHandler` wrappers doubles throughput for `image/gif` MIME types, |
| and multiplies throughput by approximately 1.5 for `text/xml` or |
| `java.awt.Image` for `image/*` types. |
| |
| [[abebp]][[GSPTG00053]][[java-server-page-and-servlet-tuning]] |
| |
| === Java Server Page and Servlet Tuning |
| |
| Many applications running on the {productName} use servlets or |
| JavaServer Pages (JSP) technology in the presentation tier. This section |
| describes how to improve performance of such applications, both through |
| coding practices and through deployment and configuration settings. |
| |
| [[abebq]][[GSPTG00170]][[suggested-coding-practices]] |
| |
| ==== Suggested Coding Practices |
| |
| This section provides some tips on coding practices that improve servlet |
| and JSP application performance. |
| |
| The following topics are addressed here: |
| |
| * link:#abebr[General Guidelines] |
| * link:#abebs[Avoid Shared Modified Class Variables] |
| * link:#abebt[HTTP Session Handling] |
| * link:#abebu[Configuration and Deployment Tips] |
| |
| [[abebr]][[GSPTG00082]][[general-guidelines]] |
| |
| ===== General Guidelines |
| |
| Follow these general guidelines to increase performance of the |
| presentation tier: |
| |
| * Minimize Java synchronization in servlets. |
| * Do not use the single thread model for servlets. |
| * Use the servlet's `init()` method to perform expensive one-time |
| initialization. |
| * Avoid using `System.out.println()` calls. |
| |
| [[abebs]][[GSPTG00083]][[avoid-shared-modified-class-variables]] |
| |
| ===== Avoid Shared Modified Class Variables |
| |
| In the servlet multithread model (the default), a single instance of a |
| servlet is created for each application server instance. All requests |
| for a servlet on that application instance share the same servlet |
| instance. This can lead to thread contention if there are |
| synchronization blocks in the servlet code. Therefore, avoid using |
| shared modified class variables because they create the need for synchronization. |
| |
| [[abebt]][[GSPTG00084]][[http-session-handling]] |
| |
| ===== HTTP Session Handling |
| |
| Follow these guidelines when using HTTP sessions: |
| |
| * Create sessions sparingly. Session creation is not free. If a session |
| is not required, do not create one. |
| * Use `javax.servlet.http.HttpSession.invalidate()` to release sessions |
| when they are no longer needed. |
| * Keep session size small, to reduce response times. If possible, keep |
| session size below 7 kilobytes. |
| * Use the directive `<%page session="false"%>` in JSP files to prevent |
| the {productName} from automatically creating sessions when they are |
| not necessary. |
| * Avoid large object graphs in an `HttpSession`. They force |
| serialization and add computational overhead. Generally, do not store |
| large objects as `HttpSession` variables. |
| * Do not cache transaction data in an `HttpSession`. Access to data in |
| an `HttpSession` is not transactional. Do not use it as a cache of |
| transactional data, which is better kept in the database and accessed |
| using entity beans. Transactions will rollback upon failures to their |
| original state. However, stale and inaccurate data may remain in |
| `HttpSession` objects. {productName} provides "read-only" |
| bean-managed persistence entity beans for cached access to read-only data. |
| |
| [[abebu]][[GSPTG00085]][[configuration-and-deployment-tips]] |
| |
| ===== Configuration and Deployment Tips |
| |
| Follow these configuration tips to improve performance. These tips are |
| intended for production environments, not development environments. |
| |
| * To improve class loading time, avoid having excessive directories in |
| the server `CLASSPATH`. Put application-related classes into JAR files. |
| * HTTP response times are dependent on how the keep-alive subsystem and |
| the HTTP server is tuned in general. For more information, see |
| link:tuning-glassfish.html#abeet[HTTP Service Settings]. |
| * Cache servlet results when possible. For more information, see |
| "link:application-development-guide/webapps.html#GSDVG00009[Developing Web Applications]" in {productName} Application Development Guide. |
| * If an application does not contain any EJB components, deploy the |
| application as a WAR file, not an EAR file. |
| |
| [[gfqnu]][[GSPTG00009]][[optimize-ssl]] |
| |
| Optimize SSL |
| |
| Optimize SSL by using routines in the appropriate operating system |
| library for concurrent access to heap space. The library to use depends |
| on the version of the Solaris Operating System (SolarisOS) that you are |
| using. To ensure that you use the correct library, set the `LD_PRELOAD` |
| environment variable to specify the correct library file. For more |
| information, refer to the following table. |
| |
| [width="100%",cols="<23%,<23%,<54%",options="header",] |
| |=== |
| |Solaris OS Version |Library |Setting of `LD_PRELOAD` Environment |
| Variable |
| |10 |`libumem3LIB` |`/usr/lib/libumem.so` |
| |
| |9 |`libmtmalloc3LIB` |`/usr/lib/libmtmalloc.so` |
| |=== |
| |
| |
| To set the `LD_PRELOAD` environment variable, edit the entry for this |
| environment variable in the `startserv` script. The `startserv` script |
| is located is located in the `bin/startserv` directory of your domain. |
| |
| The exact syntax to define an environment variable depends on the shell |
| that you are using. |
| |
| [[abebv]][[GSPTG00010]][[disable-security-manager]] |
| |
| Disable Security Manager |
| |
| The security manager is expensive because calls to required resources |
| must call the `doPrivileged()` method and must also check the resource |
| with the `server.policy` file. If you are sure that no malicious code |
| will be run on the server and you do not use authentication within your |
| application, then you can disable the security manager. |
| |
| See "link:application-development-guide/securing-apps.html#GSDVG00373[Enabling and Disabling the Security Manager]" in |
| {productName} Application Development Guide for |
| instructions on enabling or disabling the security manager. If using the |
| {productName} Administration Console, navigate to the |
| Configurations>configuration-name>Security node and check or uncheck the |
| Security Manager option as desired. Refer to the Administration Console |
| online help for more information. |
| |
| [[abebw]][[GSPTG00054]][[ejb-performance-tuning]] |
| |
| === EJB Performance Tuning |
| |
| The {productName}'s high-performance EJB container has numerous |
| parameters that affect performance. Individual EJB components also have |
| parameters that affect performance. The value of individual EJB |
| component's parameter overrides the value of the same parameter for the |
| EJB container. The default values are designed for a single-processor |
| computer system. Modify these values as appropriate to optimize for |
| other system configurations. |
| |
| The following topics are addressed here: |
| |
| * link:#abebx[Goals] |
| * link:#abeby[Monitoring EJB Components] |
| * link:#abeca[General Guidelines] |
| * link:#abecg[Using Local and Remote Interfaces] |
| * link:#abecj[Improving Performance of EJB Transactions] |
| * link:#abecs[Using Special Techniques] |
| * link:#abecv[Tuning Tips for Specific Types of EJB Components] |
| * link:#abedd[JDBC and Database Access] |
| * link:#abedi[Tuning Message-Driven Beans] |
| |
| [[abebx]][[GSPTG00171]][[goals]] |
| |
| Goals |
| ^^^^^ |
| |
| The goals of EJB performance tuning are: |
| |
| * Increased speed: Cache as many beans in the EJB caches as possible to |
| increase speed (equivalently, decrease response time). Caching |
| eliminates CPU-intensive operations. However, since memory is finite, as |
| the caches become larger, housekeeping for them (including garbage |
| collection) takes longer. |
| * Decreased memory consumption: Beans in the pools or caches consume |
| memory from the Java virtual machine heap. Very large pools and caches |
| degrade performance because they require longer and more frequent |
| garbage collection cycles. |
| * Improved functional properties: Functional properties such as user |
| timeout, commit options, security, and transaction options, are mostly |
| related to the functionality and configuration of the application. |
| Generally, they do not compromise functionality for performance. In some |
| cases, you might be forced to make a "trade-off" decision between |
| functionality and performance. This section offers suggestions in such |
| cases. |
| |
| [[abeby]][[GSPTG00172]][[monitoring-ejb-components]] |
| |
| ==== Monitoring EJB Components |
| |
| When the EJB container has monitoring enabled, you can examine |
| statistics for individual beans based on the bean pool and cache |
| settings. |
| |
| For example, the monitoring command below returns the Bean Cache |
| statistics for a stateful session bean. |
| |
| [source] |
| ---- |
| asadmin get --user admin --host e4800-241-a --port 4848 |
| -m specjcmp.application.SPECjAppServer.ejb-module. |
| supplier_jar.stateful-session-bean.BuyerSes.bean-cache.* |
| ---- |
| |
| The following is a sample of the monitoring output: |
| |
| [source] |
| ---- |
| resize-quantity = -1 |
| cache-misses = 0 |
| idle-timeout-in-seconds = 0 |
| num-passivations = 0 |
| cache-hits = 59 |
| num-passivation-errors = 0 |
| total-beans-in-cache = 59 |
| num-expired-sessions-removed = 0 |
| max-beans-in-cache = 4096 |
| num-passivation-success = 0 |
| ---- |
| |
| The monitoring command below gives the bean pool statistics for an |
| entity bean: |
| |
| [source] |
| ---- |
| asadmin get --user admin --host e4800-241-a --port 4848 |
| -m specjcmp.application.SPECjAppServer.ejb-module. |
| supplier_jar.stateful-entity-bean.ItemEnt.bean-pool.* |
| idle-timeout-in-seconds = 0 |
| steady-pool-size = 0 |
| total-beans-destroyed = 0 |
| num-threads-waiting = 0 |
| num-beans-in-pool = 54 |
| max-pool-size = 2147483647 |
| pool-resize-quantity = 0 |
| total-beans-created = 255 |
| ---- |
| |
| The monitoring command below gives the bean pool statistics for a |
| stateless bean. |
| |
| [source] |
| ---- |
| asadmin get --user admin --host e4800-241-a --port 4848 |
| -m test.application.testEjbMon.ejb-module.slsb.stateless-session-bean.slsb.bean-pool.* |
| idle-timeout-in-seconds = 200 |
| steady-pool-size = 32 |
| total-beans-destroyed = 12 |
| num-threads-waiting = 0 |
| num-beans-in-pool = 4 |
| max-pool-size = 1024 |
| pool-resize-quantity = 12 |
| total-beans-created = 42 |
| ---- |
| |
| Tuning the bean involves charting the behavior of the cache and pool for |
| the bean in question over a period of time. |
| |
| If too many passivations are happening and the JVM heap remains fairly |
| small, then the `max-cache-size` or the `cache-idle-timeout-in-seconds` |
| can be increased. If garbage collection is happening too frequently, and |
| the pool size is growing, but the cache hit rate is small, then the |
| `pool-idle-timeout-in-seconds` can be reduced to destroy the instances. |
| |
| |
| [NOTE] |
| ==== |
| Specifying a `max-pool-size` of zero (0) means that the pool is |
| unbounded. The pooled beans remain in memory unless they are removed by |
| specifying a small interval for `pool-idle-timeout-in-seconds`. For |
| production systems, specifying the pool as unbounded is NOT recommended. |
| ==== |
| |
| |
| [[abebz]][[GSPTG00086]][[monitoring-individual-ejb-components]] |
| |
| ===== Monitoring Individual EJB Components |
| |
| To gather method invocation statistics for all methods in a bean, use |
| the following command: |
| |
| [source] |
| ---- |
| asadmin get -m monitorableObject.* |
| ---- |
| |
| where monitorableObject is a fully-qualified identifier from the |
| hierarchy of objects that can be monitored, shown below. |
| |
| [source] |
| ---- |
| serverInstance.application.applicationName.ejb-module.moduleName |
| ---- |
| |
| where moduleName is `x_jar` for module `x.jar`. |
| |
| * `.stateless-session-bean.beanName .bean-pool .bean-method.methodName` |
| * `.stateful-session-bean.beanName .bean-cache .bean-method.methodName` |
| * `.entity-bean.beanName .bean-cache .bean-pool .bean-method.methodName` |
| * `.message-driven-bean.beanName .bean-pool .bean-method.methodName (methodName = onMessage)` |
| |
| For standalone beans, use this pattern: |
| |
| [source] |
| ---- |
| serverInstance.application.applicationName.standalone-ejb-module.moduleName |
| ---- |
| |
| The possible identifiers are the same as for `ejb-module`. |
| |
| For example, to get statistics for a method in an entity bean, use this |
| command: |
| |
| [source] |
| ---- |
| asadmin get -m serverInstance.application.appName.ejb-module.moduleName |
| .entity-bean.beanName.bean-method.methodName.* |
| ---- |
| |
| For more information about administering the monitoring service in |
| general, see "link:administration-guide/monitoring.html#GSADG00011[Administering the Monitoring Service]" in |
| {productName} Administration Guide. For |
| information about viewing comprehensive EJB monitoring statistics, see |
| "link:administration-guide/monitoring.html#GSADG00651[EJB Statistics]" in {productName} Administration Guide. |
| |
| To configure EJB monitoring using the {productName} Administration |
| Console, navigate to the Configurations>configuration-name>Monitoring |
| node. After configuring monitoring, you can view monitoring statistics |
| by navigating to the server (Admin Server) node and then selecting the |
| Monitor tab. Refer to the Administration Console online help for |
| instructions on each of these procedures. |
| |
| Alternatively, to list EJB statistics, use the `asadmin list` |
| subcommand. For more information, see link:reference-manual/list.html#GSRFM00145[`list`(1)]. |
| |
| For statistics on stateful session bean passivations, use this command: |
| |
| [source] |
| ---- |
| asadmin get -m serverInstance.application.appName.ejb-module.moduleName |
| .stateful-session-bean.beanName.bean-cache.* |
| ---- |
| |
| From the attribute values that are returned, use this command: |
| |
| `num-passivationsnum-passivation-errorsnum-passivation-success` |
| |
| [[abeca]][[GSPTG00173]][[general-guidelines-1]] |
| |
| ==== General Guidelines |
| |
| The following guidelines can improve performance of EJB components. Keep |
| in mind that decomposing an application into many EJB components creates |
| overhead and can degrade performance. EJB components are not simply Java |
| objects. They are components with semantics for remote call interfaces, |
| security, and transactions, as well as properties and methods. |
| |
| [[abecb]][[GSPTG00087]][[use-high-performance-beans]] |
| |
| ===== Use High Performance Beans |
| |
| Use high-performance beans as much as possible to improve the overall |
| performance of your application. For more information, see |
| link:#abecv[Tuning Tips for Specific Types of EJB Components]. |
| |
| The types of EJB components are listed below, from the highest |
| performance to the lowest: |
| |
| 1. Stateless Session Beans and Message Driven Beans |
| 2. Stateful Session Beans |
| 3. Container Managed Persistence (CMP) entity beans configured as |
| read-only |
| 4. Bean Managed Persistence (BMP) entity beans configured as read-only |
| 5. CMP beans |
| 6. BMP beans |
| |
| For more information about configuring high availability session |
| persistence, see "link:ha-administration-guide/session-persistence-and-failover.html#GSHAG00011[Configuring High Availability Session |
| Persistence and Failover]" in {productName} High |
| Availability Administration Guide. To configure EJB beans using the |
| {productName} Administration Console, navigate to the |
| Configurations>configuration-name>EJB Container node and then refer to |
| the Administration Console online help for detailed instructions. |
| |
| [[abecc]][[GSPTG00088]][[use-caching]] |
| |
| ===== Use Caching |
| |
| Caching can greatly improve performance when used wisely. For example: |
| |
| * Cache EJB references: To avoid a JNDI lookup for every request, cache |
| EJB references in servlets. |
| * Cache home interfaces: Since repeated lookups to a home interface can |
| be expensive, cache references to `EJBHomes` in the `init()` methods of |
| servlets. |
| * Cache EJB resources: Use `setSessionContext()` or `ejbCreate()` to |
| cache bean resources. This is again an example of using bean lifecycle |
| methods to perform application actions only once where possible. |
| Remember to release acquired resources in the `ejbRemove()` method. |
| |
| [[abecd]][[GSPTG00089]][[use-the-appropriate-stubs]] |
| |
| ===== Use the Appropriate Stubs |
| |
| The stub classes needed by EJB applications are generated dynamically at |
| runtime when an EJB client needs them. This means that it is not |
| necessary to generate the stubs or retrieve the client JAR file when |
| deploying an application with remote EJB components. When deploying an |
| application, it is no longer necessary to specify the `--retrieve` |
| option, which can speed up deployment. |
| |
| If you have a legacy rich-client application that directly uses the |
| CosNaming service (not a recommended configuration), then you must |
| generate the stubs for your application explicitly using RMIC. For more |
| information, see the link:troubleshooting-guide.html#GSTSG[{productName} |
| Troubleshooting Guide] for more details. |
| |
| [[abece]][[GSPTG00090]][[remove-unneeded-stateful-session-beans]] |
| |
| ===== Remove Unneeded Stateful Session Beans |
| |
| Removing unneeded stateful session beans avoids passivating them, which |
| requires disk operations. |
| |
| [[abecf]][[GSPTG00091]][[cache-and-pool-tuning-tips]] |
| |
| ===== Cache and Pool Tuning Tips |
| |
| Follow these tips when using the EJB cache and pools to improve |
| performance: |
| |
| * Explicitly call `remove()`: Allow stateful session EJB components to |
| be removed from the container cache by explicitly calling of the |
| `remove()` method in the client. |
| * Tune the entity EJB component's pool size: Entity Beans use both the |
| EJB pool and cache settings. Tune the entity EJB component's pool size |
| to minimize the creation and destruction of beans. Populating the pool |
| with a non-zero steady size before hand is useful for getting better |
| response for initial requests. |
| * Cache bean-specific resources: Use the `setEntityContext()` method to |
| cache bean specific resources and release them using the |
| `unSetEntityContext()` method. |
| * Load related data efficiently for container-managed relationships |
| (CMRs). For more information, see link:#abedc[Pre-Fetching Container |
| Managed Relationship (CMR) Beans]. |
| * Identify read-only beans: Configure read-only entity beans for read |
| only operations. For more information, see link:#abeda[Read-Only Entity |
| Beans]. |
| |
| [[abecg]][[GSPTG00174]][[using-local-and-remote-interfaces]] |
| |
| ==== Using Local and Remote Interfaces |
| |
| This section describes some considerations when EJB components are used |
| by local and remote clients. |
| |
| [[abech]][[GSPTG00092]][[prefer-local-interfaces]] |
| |
| ===== Prefer Local Interfaces |
| |
| An EJB component can have remote and local interfaces. Clients not |
| located in the same application server instance as the bean (remote |
| clients) use the remote interface to access the bean. Calls to the |
| remote interface require marshalling arguments, transportation of the |
| marshalled data over the network, un-marshaling the arguments, and |
| dispatch at the receiving end. Thus, using the remote interface entails |
| significant overhead. |
| |
| If an EJB component has a local interface, then local clients in the |
| same application server instance can use it instead of the remote |
| interface. Using the local interface is more efficient, since it does |
| not require argument marshalling, transportation, and un-marshalling. |
| |
| If a bean is to be used only by local clients then it makes sense to |
| provide only the local interface. If, on the other hand, the bean is to |
| be location-independent, then you should provide both the remote and |
| local interfaces so that remote clients use the remote interface and |
| local clients can use the local interface for efficiency. |
| |
| [[abeci]][[GSPTG00093]][[using-pass-by-reference-semantics]] |
| |
| ===== Using Pass-By-Reference Semantics |
| |
| By default, the {productName} uses pass-by-value semantics for |
| calling the remote interface of a bean, even if it is co-located. This |
| can be expensive, since clients using pass-by-value semantics must copy |
| arguments before passing them to the EJB component. |
| |
| However, local clients can use pass-by-reference semantics and thus the |
| local and remote interfaces can share the passed objects. But this means |
| that the argument objects must be implemented properly, so that they are |
| shareable. In general, it is more efficient to use pass-by-reference |
| semantics when possible. |
| |
| Using the remote and local interfaces appropriately means that clients |
| can access EJB components efficiently. That is, local clients use the |
| local interface with pass-by-reference semantics, while remote clients |
| use the remote interface with pass-by-value semantics. |
| |
| However, in some instances it might not be possible to use the local |
| interface, for example when: |
| |
| * The application predates the EJB 2.0 specification and was written |
| without any local interfaces. |
| * There are bean-to-bean calls and the client beans are written without |
| making any co-location assumptions about the called beans. |
| |
| For these cases, the {productName} provides a pass-by-reference |
| option that clients can use to pass arguments by reference to the remote |
| interface of a co-located EJB component. |
| |
| You can specify the pass-by-reference option for an entire application |
| or a single EJB component. When specified at the application level, all |
| beans in the application use pass-by-reference semantics when passing |
| arguments to their remote interfaces. When specified at the bean level, |
| all calls to the remote interface of the bean use pass-by-reference |
| semantics. See "link:application-development-guide/ejb.html#GSDVG00145[Value Added Features]" in {productName} Application Development Guide for more |
| details about the pass-by-reference flag. |
| |
| To specify that an EJB component will use pass by reference semantics, |
| use the following tag in the `sun-ejb-jar.xml` deployment descriptor: |
| |
| [source,xml] |
| ---- |
| <pass-by-reference>true</pass-by-reference> |
| ---- |
| |
| This avoids copying arguments when the EJB component's methods are |
| invoked and avoids copying results when methods return. However, |
| problems will arise if the data is modified by another source during the |
| invocation. |
| |
| [[abecj]][[GSPTG00175]][[improving-performance-of-ejb-transactions]] |
| |
| ==== Improving Performance of EJB Transactions |
| |
| This section provides some tips to improve performance when using |
| transactions. |
| |
| The following topics are addressed here: |
| |
| * link:#abeck[Use Container-Managed Transactions] |
| * link:#abecl[Do Not Encompass User Input Time] |
| * link:#abecm[Identify Non-Transactional Methods] |
| * link:#abecn[Use `TX_REQUIRED` for Long Transaction Chains] |
| * link:#abeco[Use Lowest Cost Database Locking] |
| * link:#abecp[Use XA-Capable Data Sources Only When Needed] |
| * link:#abecq[Configure JDBC Resources as One-Phase Commit Resources] |
| * link:#abecr[Use the Least Expensive Transaction Attribute] |
| |
| [[abeck]][[GSPTG00094]][[use-container-managed-transactions]] |
| |
| ===== Use Container-Managed Transactions |
| |
| Container-managed transactions are preferred for consistency, and |
| provide better performance. |
| |
| [[abecl]][[GSPTG00095]][[do-not-encompass-user-input-time]] |
| |
| ===== Do Not Encompass User Input Time |
| |
| To avoid resources being held unnecessarily for long periods, a |
| transaction should not encompass user input or user think time. |
| |
| [[abecm]][[GSPTG00096]][[identify-non-transactional-methods]] |
| |
| ===== Identify Non-Transactional Methods |
| |
| Declare non-transactional methods of session EJB components with |
| `NotSupported` or `Never` transaction attributes. These attributes can |
| be found in the `ejb-jar.xml` deployment descriptor file. Transactions |
| should span the minimum time possible since they lock database rows. |
| |
| [[abecn]][[GSPTG00097]][[use-tx_required-for-long-transaction-chains]] |
| |
| ===== Use `TX_REQUIRED` for Long Transaction Chains |
| |
| For very large transaction chains, use the transaction attribute |
| `TX_REQUIRED.` To ensure EJB methods in a call chain, use the same |
| transaction. |
| |
| [[abeco]][[GSPTG00098]][[use-lowest-cost-database-locking]] |
| |
| ===== Use Lowest Cost Database Locking |
| |
| Use the lowest cost locking available from the database that is |
| consistent with any transaction. Commit the data after the transaction |
| completes rather than after each method call. |
| |
| [[abecp]][[GSPTG00099]][[use-xa-capable-data-sources-only-when-needed]] |
| |
| ===== Use XA-Capable Data Sources Only When Needed |
| |
| When multiple database resources, connector resources or JMS resources |
| are involved in one transaction, a distributed or global transaction |
| needs to be performed. This requires XA capable resource managers and |
| data sources. Use XA capable data sources, only when two or more data |
| source are going to be involved in a transaction. If a database |
| participates in some distributed transactions, but mostly in local or |
| single database transactions, it is advisable to register two separate |
| JDBC resources and use the appropriate resource in the application. |
| |
| [[abecq]][[GSPTG00100]][[configure-jdbc-resources-as-one-phase-commit-resources]] |
| |
| ===== Configure JDBC Resources as One-Phase Commit Resources |
| |
| To improve performance of transactions involving multiple resources, the |
| {productName} uses last agent optimization (LAO), which allows the |
| configuration of one of the resources in a distributed transaction as a |
| one-phase commit (1PC) resource. Since the overhead of multiple-resource |
| transactions is much higher for a JDBC resource than a message queue, |
| LAO substantially improves performance of distributed transactions |
| involving one JDBC resource and one or more message queues. To take |
| advantage of LAO, configure a JDBC resource as a 1PC resource. Nothing |
| special needs to be done to configure JMS resources. |
| |
| In global transactions involving multiple JDBC resources, LAO will still |
| improve performance, however, not as much as for one JDBC resource. In |
| this situation, one of the JDBC resources should be configured as 1PC, |
| and all others should be configured as XA. |
| |
| [[abecr]][[GSPTG00101]][[use-the-least-expensive-transaction-attribute]] |
| |
| ===== Use the Least Expensive Transaction Attribute |
| |
| Set the following transaction attributes in the EJB deployment |
| descriptor file (`ejb-jar.xml`). Options are listed from best |
| performance to worst. To improve performance, choose the least expensive |
| attribute that will provide the functionality your application needs: |
| |
| 1. `NEVER` |
| 2. `TX_NOTSUPPORTED` |
| 3. `TX_MANDATORY` |
| 4. `TX_SUPPORTS` |
| 5. `TX_REQUIRED` |
| 6. `TX_REQUIRESNEW` |
| |
| [[abecs]][[GSPTG00176]][[using-special-techniques]] |
| |
| ==== Using Special Techniques |
| |
| Special performance-enhancing techniques are discussed in the following |
| sections: |
| |
| * link:#abect[Version Consistency] |
| * link:#abecu[Request Partitioning] |
| |
| [[abect]][[GSPTG00102]][[version-consistency]] |
| |
| ===== Version Consistency |
| |
| |
| [NOTE] |
| ==== |
| The technique in section applies only to the EJB 2.1 architecture. In |
| the EJB 3.0 architecture, use the Java Persistence API (JPA). |
| ==== |
| |
| |
| Use version consistency to improve performance while protecting the |
| integrity of data in the database. Since the application server can use |
| multiple copies of an EJB component simultaneously, an EJB component's |
| state can potentially become corrupted through simultaneous access. |
| |
| The standard way of preventing corruption is to lock the database row |
| associated with a particular bean. This prevents the bean from being |
| accessed by two simultaneous transactions and thus protects data. |
| However, it also decreases performance, since it effectively serializes |
| all EJB access. |
| |
| Version consistency is another approach to protecting EJB data |
| integrity. To use version consistency, you specify a column in the |
| database to use as a version number. The EJB lifecycle then proceeds |
| like this: |
| |
| * The first time the bean is used, the `ejbLoad()` method loads the bean |
| as normal, including loading the version number from the database. |
| * The `ejbStore()` method checks the version number in the database |
| versus its value when the EJB component was loaded. |
| |
| ** If the version number has been modified, it means that there has been |
| simultaneous access to the EJB component and `ejbStore()` throws a |
| `ConcurrentModificationException`. |
| |
| ** Otherwise, `ejbStore()` stores the data and completes as normal. |
| + |
| The `ejbStore()` method performs this validation at the end of the |
| transaction regardless of whether any data in the bean was modified. |
| |
| Subsequent uses of the bean behave similarly, except that the |
| `ejbLoad()` method loads its initial data (including the version number) |
| from an internal cache. This saves a trip to the database. When the |
| `ejbStore()` method is called, the version number is checked to ensure |
| that the correct data was used in the transaction. |
| |
| Version consistency is advantageous when you have EJB components that |
| are rarely modified, because it allows two transactions to use the same |
| EJB component at the same time. Because neither transaction modifies the |
| data, the version number is unchanged at the end of both transactions, |
| and both succeed. But now the transactions can run in parallel. If two |
| transactions occasionally modify the same EJB component, one will |
| succeed and one will fail and can be retried using the new values—which |
| can still be faster than serializing all access to the EJB component if |
| the retries are infrequent enough (though now your application logic has |
| to be prepared to perform the retry operation). |
| |
| To use version consistency, the database schema for a particular table |
| must include a column where the version can be stored. You then specify |
| that table in the `sun-cmp-mapping.xml` deployment descriptor for a |
| particular bean: |
| |
| [source,xml] |
| ---- |
| <entity-mapping> |
| <cmp-field-mapping> |
| ... |
| </cmp-field-mapping> |
| <consistency> |
| <check-version-of-accessed-instances> |
| <column-name>OrderTable.VC_VERSION_NUMBER</column-name> |
| </check-version-of-accessed-instances> |
| </consistency> |
| </entity-mapping> |
| ---- |
| |
| In addition, you must establish a trigger on the database to |
| automatically update the version column when data in the specified table |
| is modified. The {productName} requires such a trigger to use version |
| consistency. Having such a trigger also ensures that external |
| applications that modify the EJB data will not conflict with EJB |
| transactions in progress. |
| |
| For example, the following DDL illustrates how to create a trigger for |
| the `Order` table: |
| |
| [source,sql] |
| ---- |
| CREATE TRIGGER OrderTrigger |
| BEFORE UPDATE ON OrderTable |
| FOR EACH ROW |
| WHEN (new.VC_VERSION_NUMBER = old.VC_VERSION_NUMBER) |
| DECLARE |
| BEGIN |
| :NEW.VC_VERSION_NUMBER := :OLD.VC_VERSION_NUMBER + 1; |
| END; |
| ---- |
| |
| [[abecu]][[GSPTG00103]][[request-partitioning]] |
| |
| ===== Request Partitioning |
| |
| Request partitioning enables you to assign a request priority to an EJB |
| component. This gives you the flexibility to make certain EJB components |
| execute with higher priorities than others. |
| |
| An EJB component which has a request priority assigned to it will have |
| its requests (services) executed within an assigned threadpool. By |
| assigning a threadpool to its execution, the EJB component can execute |
| independently of other pending requests. In short, request partitioning |
| enables you to meet service-level agreements that have differing levels |
| of priority assigned to different services. |
| |
| Request partitioning applies only to remote EJB components (those that |
| implement a remote interface). Local EJB components are executed in |
| their calling thread (for example, when a servlet calls a local bean, |
| the local bean invocation occurs on the servlet's thread). |
| |
| [[gacmw]][[GSPTG00037]][[to-enable-request-partitioning]] |
| |
| To Enable Request Partitioning |
| |
| Follow this procedure. |
| |
| 1. Configure additional threadpools for EJB execution. |
| + |
| Using the {productName} Administration Console, navigate to the |
| Configurations>configuration-name>Thread Pools node. |
| Refer to the Administration Console online help for more information. |
| Alternatively, you can follow the instructions in |
| "link:administration-guide/threadpools.html#GSADG00008[ |
| Administering Thread Pools]" in {productName} Administration Guide. |
| + |
| Configure the threadpools as follows: |
| [arabic] |
| .. Add the additional threadpool IDs to the {productName}'s ORB. |
| + |
| This can be done on the Configurations>configuration-name>ORB node in |
| the Administration Console. |
| + |
| For example, enable threadpools named `priority-1` and `priority-2` to |
| the `<orb>` element as follows: |
| + |
| [source,xml] |
| ---- |
| <orb max-connections="1024" message-fragment-size="1024" |
| use-thread-pool-ids="thread-pool-1,priority-1,priority-2"> |
| ---- |
| |
| .. Include the threadpool ID in the `use-thread-pool-id` element of the |
| EJB component's `sun-ejb-jar.xml` deployment descriptor. |
| + |
| For example, the following `sun-ejb-jar.xml` deployment descriptor for |
| an EJB component named "`TheGreeter`" is assigned to a thread pool named `priority-2`: |
| + |
| [source,xml] |
| ---- |
| <sun-ejb-jar> |
| <enterprise-beans> |
| <unique-id>1</unique-id> |
| <ejb> |
| <ejb-name>TheGreeter</ejb-name> |
| <jndi-name>greeter</jndi-name> |
| <use-thread-pool-id>priority-1</use-thread-pool-id> |
| </ejb> |
| </enterprise-beans> |
| </sun-ejb-jar> |
| ---- |
| |
| 2. Restart the {productName}. |
| |
| [[abecv]][[GSPTG00177]][[tuning-tips-for-specific-types-of-ejb-components]] |
| |
| ==== Tuning Tips for Specific Types of EJB Components |
| |
| This section provides tips for tuning various specific types of EJB components: |
| |
| * link:#abecw[Entity Beans] |
| * link:#abecx[Stateful Session Beans] |
| * link:#abecz[Stateless Session Beans] |
| * link:#abeda[Read-Only Entity Beans] |
| * link:#abedc[Pre-Fetching Container Managed Relationship (CMR) Beans] |
| |
| These components can all be configured in the {productName} |
| Administration Console from the Configurations>configuration-name>EJB |
| Container node. Alternatively, you can perform these configurations by |
| following the instructions in "link:ha-administration-guide/rmi-iiop.html#GSHAG00013[ |
| RMI-IIOP Load Balancing and Failover]" |
| in {productName} High Availability Administration Guide. |
| |
| [[abecw]][[GSPTG00104]][[entity-beans]] |
| |
| ===== Entity Beans |
| |
| Depending on the usage of a particular entity bean, one should tune |
| `max-cache-size` so that the beans that are used less frequently (for |
| example, an order that is created and never used after the transaction |
| is over) are cached less, and beans that are used frequently (for |
| example, an item in the inventory that gets referenced very often), are |
| cached more. |
| |
| [[abecx]][[GSPTG00105]][[stateful-session-beans]] |
| |
| ===== Stateful Session Beans |
| |
| When a stateful bean represents a user, a reasonable `max-cache-size` of |
| beans is the expected number of concurrent users on the application |
| server process. If this value is too low (in relation to the steady load |
| of users), beans would be frequently passivated and activated, causing a |
| negative impact on the response times, due to CPU intensive |
| serialization and deserialization as well as disk I/O. |
| |
| Another important variable for tuning is `cache-idle-timeout-in-seconds` |
| where at periodic intervals of `cache-idle-timeout-in-seconds`, all the |
| beans in the cache that have not been accessed for more than |
| `cache-idle-timeout-in-seconds` time, are passivated. Similar to an HTTP |
| session timeout, the bean is removed after it has not been accessed for |
| `removal-timeout-in-seconds`. Passivated beans are stored on disk in |
| serialized form. A large number of passivated beans could not only mean |
| many files on the disk system, but also slower response time as the |
| session state has to be de-serialized before the invocation. |
| |
| [[abecy]][[GSPTG00011]][[checkpoint-only-when-needed]] |
| |
| Checkpoint only when needed |
| |
| In high availability mode, when using stateful session beans, consider |
| checkpointing only those methods that alter the state of the bean |
| significantly. This reduces the number of times the bean state has to be |
| checkpointed into the persistent store. |
| |
| [[abecz]][[GSPTG00106]][[stateless-session-beans]] |
| |
| ===== Stateless Session Beans |
| |
| Stateless session beans are more readily pooled than entity or the |
| stateful session beans. Valid values for `steady-pool-size`, |
| `pool-resize-quantity` and `max-pool-size` are the best tunables for |
| these type of beans. Set the `steady-pool-size` to greater than zero if |
| you want to pre-populate the pool. This way, when the container comes |
| up, it creates a pool with `steady-pool-size` number of beans. By |
| pre-populating the pool it is possible to avoid the object creation time |
| during method invocations. |
| |
| Setting the `steady-pool size` to a very large value can cause unwanted |
| memory growth and can result in large garbage collection times. |
| `pool-resize-quantity` determines the rate of growth as well as the rate |
| of decay of the pool. Setting it to a small value is better as the decay |
| behaves like an exponential decay. Setting a small `max-pool-size` can |
| cause excessive object destruction (and as a result excessive object |
| creation) as instances are destroyed from the pool if the current pool |
| size exceeds `max-pool-size`. |
| |
| [[abeda]][[GSPTG00107]][[read-only-entity-beans]] |
| |
| ===== Read-Only Entity Beans |
| |
| Read-only entity beans cache data from the database. {productName} |
| supports read-only beans that use both bean-managed persistence (BMP) |
| and container-managed persistence (CMP). Of the two types, CMP read-only |
| beans provide significantly better performance. In the EJB lifecycle, |
| the EJB container calls the `ejbLoad()` method of a read-only bean once. |
| The container makes multiple copies of the EJB component from that data, |
| and since the beans do not update the database, the container never |
| calls the `ejbStore()` method. This greatly reduces database traffic for |
| these beans. |
| |
| If there is a bean that never updates the database, use a read-only bean |
| in its place to improve performance. A read-only bean is appropriate if |
| either: |
| |
| * Database rows represented by the bean do not change. |
| * The application can tolerate using out-of-date values for the bean. |
| |
| For example, an application might use a read-only bean to represent a |
| list of best-seller books. Although the list might change occasionally |
| in the database (say, from another bean entirely), the change need not |
| be reflected immediately in an application. |
| |
| The `ejbLoad()` method of a read-only bean is handled differently for |
| CMP and BMP beans. For CMP beans, the EJB container calls `ejbLoad()` |
| only once to load the data from the database; subsequent uses of the |
| bean just copy that data. For BMP beans, the EJB container calls |
| `ejbLoad()` the first time a bean is used in a transaction. Subsequent |
| uses of that bean within the transaction use the same values. The |
| container calls `ejbLoad()` for a BMP bean that doesn't run within a |
| transaction every time the bean is used. Therefore, read-only BMP beans |
| still make a number of calls to the database. |
| |
| To create a read-only bean, add the following to the EJB deployment |
| descriptor `sun-ejb-jar.xml`: |
| |
| [source,xml] |
| ---- |
| <is-read-only-bean>true</is-read-only-bean> |
| <refresh-period-in-seconds>600</refresh-period-in-seconds> |
| ---- |
| |
| [[abedb]][[GSPTG00012]][[refresh-period]] |
| |
| Refresh Period |
| |
| An important parameter for tuning read-only beans is the refresh period, |
| represented by the deployment descriptor entity |
| `refresh-period-in-seconds`. For CMP beans, the first access to a bean |
| loads the bean's state. The first access after the refresh period |
| reloads the data from the database. All subsequent uses of the bean uses |
| the newly refreshed data (until another refresh period elapses). For BMP |
| beans, an `ejbLoad()` method within an existing transaction uses the |
| cached data unless the refresh period has expired (in which case, the |
| container calls `ejbLoad()` again). |
| |
| This parameter enables the EJB component to periodically refresh its |
| "snapshot" of the database values it represents. If the refresh period |
| is less than or equal to 0, the bean is never refreshed from the |
| database (the default behavior if no refresh period is given). |
| |
| [[abedc]][[GSPTG00108]][[pre-fetching-container-managed-relationship-cmr-beans]] |
| |
| ===== Pre-Fetching Container Managed Relationship (CMR) Beans |
| |
| If a container-managed relationship (CMR) exists in your application, |
| loading one bean will load all its related beans. The canonical example |
| of CMR is an order-orderline relationship where you have one `Order` EJB |
| component that has related `OrderLine` EJB components. In previous |
| releases of the application server, to use all those beans would require |
| multiple database queries: one for the `Order` bean and one for each of |
| the `OrderLine` beans in the relationship. |
| |
| In general, if a bean has n relationships, using all the data of the |
| bean would require n+1 database accesses. Use CMR pre-fetching to |
| retrieve all the data for the bean and all its related beans in one |
| database access. |
| |
| For example, you have this relationship defined in the `ejb-jar.xml` |
| file: |
| |
| [source,xml] |
| ---- |
| <relationships> |
| <ejb-relation> |
| <description>Order-OrderLine</description> |
| <ejb-relation-name>Order-OrderLine</ejb-relation-name> |
| <ejb-relationship-role> |
| <ejb-relationship-role-name> |
| Order-has-N-OrderLines |
| </ejb-relationship-role-name> |
| <multiplicity>One</multiplicity> |
| <relationship-role-source> |
| <ejb-name>OrderEJB</ejb-name> |
| </relationship-role-source> |
| <cmr-field> |
| <cmr-field-name>orderLines</cmr-field-name> |
| <cmr-field-type>java.util.Collection</cmr-field-type> |
| </cmr-field> |
| </ejb-relationship-role> |
| </ejb-relation> |
| </relationships> |
| ---- |
| |
| When a particular `Order` is loaded, you can load its related |
| `OrderLines` by adding this to the `sun-cmp-mapping.xml` file for the |
| application: |
| |
| [source,xml] |
| ---- |
| <entity-mapping> |
| <ejb-name>Order</ejb-name> |
| <table-name>...</table-name> |
| <cmp-field-mapping>...</cmp-field-mapping> |
| <cmr-field-mapping> |
| <cmr-field-name>orderLines</cmr-field-name> |
| <column-pair> |
| <column-name>OrderTable.OrderID</column-name> |
| <column-name>OrderLineTable.OrderLine_OrderID</column-name> |
| </column-pair> |
| <fetched-with> |
| <default> |
| </fetched-with> |
| </cmr-field-mapping> |
| </entity-mappping> |
| ---- |
| |
| Now when an `Order` is retrieved, the CMP engine issues SQL to retrieve |
| all related `OrderLines` with a `SELECT` statement that has the |
| following `WHERE` clause: |
| |
| [source,sql] |
| ---- |
| OrderTable.OrderID = OrderLineTable.OrderLine_OrderID |
| ---- |
| |
| This clause indicates an outer join. These `OrderLines` are pre-fetched. |
| |
| Pre-fetching generally improves performance because it reduces the |
| number of database accesses. However, if the business logic often uses |
| `Orders` without referencing their `OrderLines`, then this can have a |
| performance penalty, that is, the system has spent the effort to |
| pre-fetch the `OrderLines` that are not actually needed. |
| |
| Avoid pre-fetching for specific finder methods; this can often avoid |
| that penalty. For example, consider an order bean has two finder |
| methods: a `findByPrimaryKey` method that uses the `Orderlines`, and a |
| `findByCustomerId` method that returns only order information and |
| therefore does not use the `Orderlines`. If you have enabled CMR |
| pre-fetching for the `Orderlines`, both finder methods will pre-fetch |
| the `Orderlines`. However, you can prevent pre-fetching for the |
| `findByCustomerId` method by including this information in the |
| `sun-ejb-jar.xml` descriptor: |
| |
| [source,xml] |
| ---- |
| <ejb> |
| <ejb-name>OrderBean</ejb-name> |
| ... |
| <cmp> |
| <prefetch-disabled> |
| <query-method> |
| <method-name>findByCustomerId</method-name> |
| </query-method> |
| </prefetch-disabled> |
| </cmp> |
| </ejb> |
| ---- |
| |
| [[abedd]][[GSPTG00178]][[jdbc-and-database-access]] |
| |
| ==== JDBC and Database Access |
| |
| The following are some tips to improve the performance of database |
| access: |
| |
| * link:#abede[Use JDBC Directly] |
| * link:#abedf[Encapsulate Business Logic in Entity EJB Components] |
| * link:#abedg[Close Connections] |
| * link:#abedh[Minimize the Database Transaction Isolation Level] |
| |
| [[abede]][[GSPTG00109]][[use-jdbc-directly]] |
| |
| ===== Use JDBC Directly |
| |
| When dealing with large amounts of data, such as searching a large |
| database, use JDBC directly rather than using Entity EJB components. |
| |
| [[abedf]][[GSPTG00110]][[encapsulate-business-logic-in-entity-ejb-components]] |
| |
| ===== Encapsulate Business Logic in Entity EJB Components |
| |
| Combine business logic with the Entity EJB component that holds the data |
| needed for that logic to process. |
| |
| [[abedg]][[GSPTG00111]][[close-connections]] |
| |
| ===== Close Connections |
| |
| To ensure that connections are returned to the pool, always close the |
| connections after use. |
| |
| [[abedh]][[GSPTG00112]][[minimize-the-database-transaction-isolation-level]] |
| |
| ===== Minimize the Database Transaction Isolation Level |
| |
| Use the default isolation level provided by the JDBC driver rather than |
| calling `setTransactionIsolationLevel()`, unless you are certain that |
| your application behaves correctly and performs better at a different |
| isolation level. |
| |
| Reduce the database transaction isolation level when appropriate. |
| Reduced isolation levels reduce work in the database tier, and could |
| lead to better application performance. However, this must be done after |
| carefully analyzing the database table usage patterns. |
| |
| To set the database transaction isolation level using the {productName} Administration Console, navigate to the Resources>JDBC>JDBC |
| Connection Pools>pool-name node. Refer to the Administration Console |
| online help for complete instructions. Alternatively, follow the |
| instructions in "link:administration-guide/jdbc.html#GSADG00015[Administering Database Connectivity]" |
| in {productName} Administration Guide. For more |
| information on tuning JDBC connection pools, see |
| link:tuning-glassfish.html#abehq[JDBC Connection Pool Settings]. |
| |
| [[abedi]][[GSPTG00179]][[tuning-message-driven-beans]] |
| |
| ==== Tuning Message-Driven Beans |
| |
| This section provides some tips to improve performance when using JMS |
| with message-driven beans (MDBs). |
| |
| [[abedj]][[GSPTG00113]][[use-getconnection]] |
| |
| ===== Use `getConnection()` |
| |
| JMS connections are served from a connection pool. This means that |
| calling `getConnection()` on a Queue connection factory is fast. |
| |
| [[abedk]][[GSPTG00114]][[tune-the-message-driven-beans-pool-size]] |
| |
| ===== Tune the Message-Driven Bean's Pool Size |
| |
| The container for message-driven beans (MDB) is different than the |
| containers for entity and session beans. In the MDB container, sessions |
| and threads are attached to the beans in the MDB pool. This design makes |
| it possible to pool the threads for executing message-driven requests in |
| the container. |
| |
| Tune the Message-Driven bean's pool size to optimize the concurrent |
| processing of messages. Set the size of the MDB pool to, based on all |
| the parameters of the server (taking other applications into account). |
| For example, a value greater than 500 is generally too large. |
| |
| To configure MDB pool settings in the {productName} Administration |
| Console, navigate to the Configurations>configuration-name>EJB Container |
| node and then select the MDB Settings tab. Refer to the Administration |
| Console online help for more information. Alternatively, you can set the |
| MDB pool size by using the following `asadmin set` subcommand: |
| |
| [source] |
| ---- |
| asadmin set server.mdb-container.max-pool-size = value |
| ---- |
| |
| [[abedl]][[GSPTG00115]][[cache-bean-specific-resources]] |
| |
| ===== Cache Bean-Specific Resources |
| |
| Use the `setMessageDrivenContext()` or `ejbCreate()` method to cache |
| bean specific resources, and release those resources from the |
| `ejbRemove()` method. |
| |
| [[abedm]][[GSPTG00116]][[limit-use-of-jms-connections]] |
| |
| ===== Limit Use of JMS Connections |
| |
| When designing an application that uses JMS connections make sure you |
| use a methodology that sparingly uses connections, by either pooling |
| them or using the same connection for multiple sessions. |
| |
| The JMS connection uses two threads and the sessions use one thread |
| each. Since these threads are not taken from a pool and the resultant |
| objects aren't pooled, you could run out of memory during periods of |
| heavy usage. |
| |
| One workaround is to move `createTopicConnection` into the `init` of the |
| servlet. |
| |
| Make sure to specifically close the session, or it will stay open, which |
| ties up resources. |