gravatar

EJB's and Exceptions

EJB's and Exceptions
From an EJB method, if any unchecked excpetion is thrown, then it will be encapsulated in EJBException object...All checked exceptions are propagated without getting encapsulated by any other exception..

This is true for both Stateful and Stateless EJB's

Session Beans  and Exceptions
Whenever an EJB method throws any uncheked exception, then the container invalidates the EJB instance...During this process the container does'nt call the lifecycle listener method marked with PreDestroy...
When a checked exception is thrown, then the EJB instance is not invalidated...

When we say invalidated, it can mean many things..Its exactly implementation depends on the Application Server...However, the main thing to know is that, all further EJB method calls will be dealt by a different EJB instance...Some servers, might destroy the EJB completely...while some servers, return the instance to the EJB instance pool...

For Stateful Bean also when an Unchecked exception is thrown, the EJB Bean is completely destroyed...So we cannot call any other methods of the stateful EJB bean once an Uncheked exception is thrown (In case of stateful EJB, we can continue calling EJB methods, as a new EJB instance will be assigned for each method invocation)...For Checked exception, there is no problem...just like in stateless EJB..

@PreDestroy lifecycle callback method

The @PreDestroy method may not be called in all situations...When a Bean (stateful or stateless) is invalidated  then the method marked with the annotation "PreDestroy" does'nt get called...When the session bean timesout, the server may not call this lifecycle method (You have to contact the server doc for this)..

When a stateful bean has a method that is marked with the @Remove annotation and when the client calls this method, then the method marked with the annotation @PreDestroy will be called...

NOTE: When a method is marked with @Remove and @PreDestroy, then the method will be called twice when a client invokes the method once...

gravatar

JavaEE servlets important tags and their usage

An example of how to use resource-ref tag is provided at the following location..


http://onjava.com/pub/a/onjava/excerpt/jsvltjspckbk_chap01/index.html?page=2

An example of how to use resource-env-ref tag in the DD is provided at the following location...

http://tomcat.apache.org/tomcat-5.5-doc/jndi-resources-howto.html

gravatar

mime-mapping

A servlet may need to know which MIME type a file extension corresponds to , and such a mapping needs to be specified as follows..

<mime-mapping>
       <extension>txt</extension>
        <mime-type>text/html</mime-type>
</mime-mapping>

In the service/doGet/doPost methods, use the following code to determine the mimetype of the file

String mimeType=this.getServletContext().getMimeType("pathOfTheFile.txt");
response.setContentType(mimeType);

gravatar

EL expressions

EL expressions handle null values gracefully in some cases...The following are the cases..

  • If the EL expression is of the following form ${attribute.xxxxxx} or ${bean.xxxx} and if the "attribute" or "bean"  is not present in any of the scopes
  • If the EL expression is of the following form ${map.key.xxxx} and if the key is not present in the map
  • If the EL expression is of the following form ${list_or_array[index]} and even if the index value is out of bounds..
EL expressions throws error in the following cases..
  • If the EL expresseion is of the following form ${bean.property} or ${bean["property"]} and if the "property" is not present in the bean.

gravatar

Validating an XML file using XSD

The following document talks about the diferrent ways in which you can validate an XML file using XSD in your application.

http://java.sun.com/j2ee/1.4/docs/tutorial/doc/JAXPDOM8.html

gravatar

XML Namespaces Basics

If you want to understand the concepts of XML namespaces, you need to ask few questions as follows...and get answers for them

  • What are namespaces
  • Why are namespaces used
  • When are namespaces used
  • What is the connection between XML, XML namespace and XSD/DTD
So let me give my answers for the above questions..

What are namespaces and what do they provide?

XML namespace is a way to group elemens of an XML file, inorder to avoid element naming conflicts...
XML namespace allows the XML parsers to process elements differently even if the elements have the same name.

Why does a parser has to process elements differently when the element names are same?

To answer this question...i have to take an example..

Assume that you have a XML file with the following content...

<organization>
           <projectlead>
                      <employeeid>123</employeeid>
           </projectlead>
</organization>

Assume that you have a parser (a java program)which can read the above XML file and lists out the Employee ID's..What the parser does is, gets all the "EmployeeID" elements in the XML file and then prints the value of the text node child element.

Now after sometime, someone comes and changes the XML file as follows..assuming that the java parser which is already present, will not list the EmployeeId of the "MYProjLead" element...

<organization>
           <projectlead>
                      <employeeid>123</employeeid>
         </projectlead>

           <myprojlead>
                     <employeeid>1233</employeeid>
           </myprojlead>
</organization>


But the parser lists out even the value of the EmployeeID  element present under "MYProjLead"...But this is not what is required...We want the parser to process only the "EmployeeID" elements present in the "ProjectLead"...
This is an example where the parser has to process the same Element  differently as they are present in different context...

This context can be specified explicitly using the XML namespace...So once we specify in which context an XML element is present, parsers can process elements differently based on the context (XML Namespace)...

So How do we specify the context ?

In XML we specify the context using a namespace as follows.

<organization>
           <projectlead xmlns="http://projectLeaderContext">
                      <employeeid>123</employeeid>
         </projectlead>

           <myprojlead xmlns="http://someCustomProjectLeaderContext">
                     <employeeid>1233</employeeid>
           </myprojlead>
</organization>

The context (actually the namespace) is specified using the "xmlns" attribute..

gravatar

ADFbc commit phase information

Many times it will be useful to understand what happens during the commit phase in ADFbc. It is very much useful to know when the validation happens, when the post changes happen etc..

The following sequence happens when a commit is successful.

  1. Validation phase : During this phase all the entities which are marked as modified are validated.
  2. Post changes phase: This is the phase where changes from the middle tier will be pushed to the database but will not be commited. This phase consists of two things


    • Lock phase: Where each row that has to be updated will be locked in the database.
    • Prepare for DML phase:  This is the place where you can modify the values of any entity attribute,if you want to before the changes are posted.
    • Do DML phase: Where the actual dml statement is fired.


  3. Commit Phase: When all the above phases are executed without any problem, the commit happens in this phase.
The following are the EntityImpl methods which will be called in the above phases.


  • Validation Phase: validateEntity()
  • Post changes Phase : postChanges(TransactionEvent e)
  • Lock Phase: lock()
  • Prepare for DML: prepareForDML(int operation,TransactionEvent e)
  • Do DML phase: doDML(int operation, TransactionEvent event)
  • After Posting is done: donePostingAll(TransactionEvent transactionEvent) 
  • Before Commit: beforeCommit(TransactionEvent transactionEvent)
  • After Commit: afterCommit(TransactionEvent transactionEvent)

gravatar

Executing commands in sub shell

Normally, a shell script is nothing but a series of commands to be executed. Some commands open up a sub shell and will prevent the remaining commands in the script from getting executed..

To run such commands in the sub shell opened by the command use the
-exec option..

For example when you use the ADE commands like

ade useview view_name

a new subshell will be created..In this new sub shell, if you want to run any command, do the following..

Create a new shell script which contains all the commands to be executed in the sub shell ..for example

subshellcommands.sh
------------------------
ade pwv
cd $ADE_VIEW_ROOT/bin
ant -f build.xml build

Now the actual script that contains the ade useview command should be as follows..

mainscript.sh
-------------
ade useview -exec /full/path/of/the/file/subshellcommands.sh view_name

gravatar

Deferred VS Immediate EL expressions

Found a good article which explains the differences between the usage of the EL expressions like
${expr} (immediate) and
#{expr} (deferred)

Here is the link

Here are some of the important points from the article (in case if you don't want to follow the link..

The primary limitation of the JSP EL (expressiongs like ${expr}) is that its expressions are evaluated immediately, meaning that the JSP container immediately parses and resolves the expression when it processes the page and returns a response.

Immediate evaluation is sufficient when a JavaServer Faces page is rendered for the first time. However, after the user enters values into the UI components and submits the page again, those values are converted, validated, and propagated to server-side data objects, and component events are processed. In order to convert data to the proper type, validate it, store it in an external object, and process events in an orderly fashion, the JavaServer Faces life cycle is split into separate phases to handle each of these tasks. Therefore, it must be possible to evaluate expressions at different phases of the life cycle rather than immediately, as is done in JSP technology.

Another problem with the immediate evaluation of expressions is that it is done in read-only mode. JavaServer Faces components need to be able to get data from server-side objects during the rendering phase and set the data in the server-side objects during postback.

Finally, JavaServer Faces components need a way to invoke methods on server-side objects during various stages of the life cycle in order to validate data and handle component events. JSP functions are not sufficient because they can only be used to call static methods defined in a TLD file; they cannot be used to dynamically invoke public methods on objects.

gravatar

Adding a dynamic where clause using named bind variables

The following piece of code is used to set a dynamic where clause to a view object. It also shows how to set  values to the named bind parameters present in the dynamic where clause.

    public void addWhereClauseWithNamedBindParams(){
        ViewObject vo=this.getEmp1();
       
      
        vo.setWhereClause(null);
       
        vo.setWhereClause("Empno=:eNo");
        vo.defineNamedWhereClauseParam("eNo",new Integer("7369"),null);
        vo.executeQuery();
       
        vo.removeNamedWhereClauseParam("eNo");
        vo.setWhereClause(null);
    }

gravatar

Adding a dynamic where clause using positional parameters

The following piece of code shows how to add a dynamic where clause to a view object .
It also shows how to set the bind parameters (using the positioning style not the named bind parameters)

    public void addWhereClause(){
        ViewObject vo=this.getEmp1();
       
        vo.setWhereClauseParams(null);
        vo.setWhereClause(null);
       
        vo.setWhereClause("Empno=:1");
        vo.setWhereClauseParam(0,new Integer("7369"));
        // you can also use the following code to set the positional parameters.
        // vo.setWhereClauseParams(new Object[]{new Integer("7369")});
        //
        // The difference between the two apis is that one explicitly provides
        // the bind parameter position and in the second one the position is implicity
       
        vo.executeQuery();
       
        vo.setWhereClauseParams(null);
        vo.setWhereClause(null);
    }

Using the "setWhereClauseParam" or "setWhereClauseParams" api's you cannot set the named bind parameters....

gravatar

Warning on unsaved changes

http://www.oracle.com/technology/products/adf/patterns/11.1.1.1.0/UnsavedDataWarning.html

gravatar

Storing non-serializable objects

In many cases there are requirements, where every user session needs a seperate object to be used throughout the session.
For example, let us take the example where there is requirement to access the SOA related data from the Application Module. To access the data from the SOA server, a connection has to be established to the SOA server and then appropriate data has to be queried. The same connection cannot be used by all users (or cannot be used in all user sessions). Every user session should have a seperate connection, so that when queries are executed, only the data related to the user are fetched. So for every user session, a seperate connection object is required.

So how can we make evey user have a seperate unserializable object?

The simplest way to achieve this is to re-create the object every time it is required. But in many cases, recreating such objects can have serious performance implications. So what else can be done?

The only other thing that can be done is to minimize the number of times the object is re-created.
This can be achieved by storing the non-serializable objects in the session of the DB transaction associated to the Application module.

The following piece of code shows how to do that..

getDBTransaction().getSession().getUserData().put("key",non_serializable_obj_instance);

So the overall procedure should be as follows..

  • Check whether the require object is present in the user session
  • If the object is present , just it
  • If the object is not present, create an instance of the object. Put a reference of the object in the session and use the reference.
The session associated to the transaction, gets re-initialized whenever passivation/activation happens. So all the objects placed in the session will be gone after the passivation/activation cycle.

gravatar

Basic information about xsd's and namespace

An xsd file can refer to another xsd file in two ways..

  • using <import> tags
  • using <include> tags
The <import> tag has to be used, when an xsd wants to refer another xsd whose "targetNamespace" values is different.
The <include> tag has to be used, when the "targetNamespace" of the referred xsd is same as the "targetNamespace" of the referring xsd..
You cannot "import" an xsd whose "targetNamespace" is same as the "targeNamespace" of the referring xsd file...
Similarly, you cannot "include" an xsd whose "targetNamespace" is different from the "targetNamespace" of the referring xsd file.

gravatar

Populating Primary Key of Entities in 11g

Its a common requirement to populate the primary key of an entity automatically, as soon as an entity is created.

There are many ways to populate the primary key of an entity. There are programmatic ways to populate the primary key. Also there are ways to populate the primary keys based on a database sequence.

In 11g ADFbc can auto populate the primary key of an entity if the java type of the attribute is "java.lang.Long". This is done declaratively. Select the attribute whose value should be populated automatically. Then go to the property inspector. Expand the "Applications" tab and then change the drop down with the label "Application Unique ID" to "true".

That's it..

But for this to work properly, the database that is used for fetching the information should have a table with the name like "S_ROW_ID" and there are many other requirements..If you use the latest 11g database then there is nothing to worry about.

If this does'nt work for you and have to populate the attribute with a value of a DB sequence then do the following .

Select the attribute , whose value has to come from the DB sequence. Go to the property inspector. Expand the "Value" tab and select "Expression" as the "Default value type" radio button. In the "Default Value" input field, provide a groovy expression like "(new oracle.jbo.server.SequenceImpl("DB_Sequence_name",object.getDBTransaction())).getSequenceNumber()"

There are many other ways to populate the primary key. Look into the online documentation for this.

gravatar

Basics of AM pooling

Basically, every user request will be given an AM instance from the AM pool. Before the response for the user request is sent back to the client, the AM instance will be saved back to the AM pool. A user may not be given the AM instance which was given to him previously. This can happen, when all the free AM instances have been used up . Before giving an AM instance to a user, ADFbc checks if the AM instance has been serving the previous requests of the user. If not, the framework will passivate all the AM state and will re-intialize its state so that it can start serving the new user.

During this entire process, there are few hook points in the Application Module class where the developer can have custom logic to implement his requirements. The most important of these hook points is the method "prepareSession(Session sessionParam)".

This method will be called, in the following cases.

  • When there are free AM instances, and a user has sent a request for the first time.
  • When all the free AM instances are used up and one on the AM instances has to serve the request of a new user.

gravatar

Entity States (Entity Life cycle)



The above picture explains how an entity object moves from one state to another..

When an entity row is in memory, it has an entity state that reflects the logical state of the row. When an entity row is first created, its status is New. You can use the setNewRowState() method to mark the entity as being Initialized, which removes it from the transaction's list of pending changes until the user sets at least one of its attributes, at which time it returns to the New state. This allows you to create more than one initialized row and post only those that the user modifies.

The Unmodified state reflects an entity that has been retrieved from the database and has not yet been modified. It is also the state that a New or Modified entity transitions to after the transaction successfully commits. During the transaction in which it is pending to be deleted, an Unmodified entity row transitions to the Deleted state. Finally, if a row that was New and then was removed before the transaction commits, or Unmodified and then successfully deleted, the row transitions to the Dead state.

You can use the getEntityState() method to access the current state of an entity row in your business logic code.

If you use the postChanges() method to post pending changes without committing the transaction yet, the getPostState() method returns the entity's state from the point of view of it's being posted to the database or not. For example, a new entity row that has been inserted into the database due to your calling the postChanges()method programmatically — but which has not yet been committed — will have a different value for getPostState() and getEntityState(). The getPostState() method will reflect an "Unmodified" status since the new row has been posted, however the getEntityState() will still reflect that the entity is New in the current transaction.

gravatar

Does every master entity row has a seperate RowSet object

Yes every master entity row has a seperate RowSet object containing all its child rows...

Let us take the Department and Employee tables...Assume that the primary key of the department table is the "DepartmentName" and not the "DepartmentId"... Let us say that there is an association between the Department entity and the Employee entity based on the "DepartmentId" attribute, so that the Department entity is the master and the Employee entity is the child..

So for every department row, there should be a RowSet using which all the associated Employee's can be found...

Even if there are two deparment rows having the same "DepartmentId" values, each row will have a seperate RowSet object...but both the RowSet objects will be pointing to the same iterator...

So if multiple master rows have the same source attribute value , then ADF bc is clever enough to fetch all the rows from the middle tier instead of firing queries to the database to fetch the child rows...

This is true even if the association accessors are retained.

Does this mean anything?

This information is given just to explain that ADFbc is good at deciding when it has to go to database and whether it can fetch all the necessary information from the middle tier

gravatar

Retaining Association accessor

In BC4J its easy to create a parent-child relationships between entity objects. This is done using the entity association objects.

Every time when an entity association accessor is accessed, ADF bc by default creates a new RowSet object containing all the child rows associated to the current parent entity object. This does not mean that an sql query will be re-executed to fetch all the child rows . This only means that a new instance of a RowSet object will be created with its default iterator reset to the "slot" before the first row. To force the row set to refresh its rows from the database, executeQuery() method has to be called.

Since there is a small amount of overhead associated with creating the row set, if your code makes numerous calls to the same association accessor attributes, you can consider enabling the association accessor row set retention for the source entity object in the association. You can enable retention of the association accessor row set using the overview editor for the entity object that is the source for the association accessor. Select Retain Association Accessor Row Set in the Tuning section of the General page of the overview editor for the entity object.


When this feature is enabled for an entity object, since the association accessor row set is not recreated each time, the current row of the RowSet object is also retained as a side-effect. This means that inorder to reset the currency of the row set , the "reset" method has to be called on the row set object. A failure to call reset() each time before the rowset is iterated, can result in hard-to-detect error in your application.

So the best way to iterate through the rows is to have code as follows..

RowSet rs=.....

rs.reset();

while(rs.hasNext()){
Row row=rs.next();
}
So irrespective of whether the association accessor is retained or not, this code will help to scroll through all the rows of the row set...

The method "rs.hasNext()" might fire an sql query , if its the first time the row set is being called. So only the first time a rowset is being scrolled, the framework fires an SQL query and populates the row set..In other cases, the method "hasNext()" will just check if there is any row in the entity cache or not....

If you always want to access all the rows that have been created in the middle tier as well as all the rows from the database use the following piece of code..

RowSet rs=.....

rs.executeQuery();

while(rs.hasNext()){
Row row=rs.next();
}

This code works irrespecitive of whether the association accessors are retained or not...This code will fetch all the new rows from the middle tier and all the rows (even the new rows commited to the database from backend ) from the database...

Programmatically setting the association accessor retention

To programmatically set the association accessor retention do the following..

Generate the Entity Collection class...In this class, there should be a method like "init()"...In this method, after the line "super.init();" call the method "setAssociationAccessorRetained(true)", by passing "true" as parameter...

gravatar

Accessing the current locale context

In BC4J , every application module is associated to a locale context object. To access the locale context object associated to the application module use the code snippet given below.

ApplicationModule am=.....
am.getSession().getLocaleContext();

gravatar

Accessing Custom Propeties of Entities

BC4J allows custom properties to be associated to each entity/view object. This can be done declaratively using the overview editor of each object.

To access the value of a custom property (either translated one or the non-translated one), use the following piece of code..

Accessing the custom property value from an entity class

this.getEntityDef().getProperty("propertyName");

The "propertyName" is the name of the property whose value is needed. The property can also be a translatable property. If the property is a translatable property, the above piece of code will fetch the translated value of the LocaleContext associated to the session of the application module..

If the translated value of some other LocaleContext is required then use the following piece of code.

this.getEntityDef().getProperty("propertyName", localeContextObject);

where "localeContextObject" is a java object of type oracle.jbo.LocaleContext.

Accessing the custom property value in viewobject class

In the Impl class just use the method "getProperty"..This takes the same parameters as explained above..

gravatar

Alternate Keys of Entities

All database tables related to functional products, generally have a primary key. In many cases there will be alteast one surrogate key (also called the Alternate key or the Unique key) for each table.

For example , if Employee table is considered, generally "employeeId" will be the primary key. But there can be other columns like "employeeEmail" which has to be unique for each and every employee. Even though this restriction may not be present in the database (i.e database constraint may not be present), functionally it may be required to implement the unique constraint in the middle tier.

BC4J allows you to setup such unique constriants for each entity. This can be done using the Alternate Keys feature.

Using this feature, a set of attributes (of the entity) can be marked to form on alternate keys. Every entity can have more than one alternate key.

So when should alternate keys be created? And what are the advantages of using alternate keys? The following are some of the advantages of using alternate keys.

  1. Business functionality might require a unique key constraint on a set of attributes, and the unique key constraint may not be present at the database level. Then the requirement can be satisfied creating alternate keys. (NOTE: Alternate keys can be created even if there are database constraints)..
  2. Alternate keys are useful for direct row lookups via the "findByAltKey" of the Entity definition.
  3. When alternate keys are created, it becomes easy to check that all entities have unique values for the set of attributes marked as alternate key. Declarative validators can be used to perform this check and to provide appropriate error message. (Even if there are no declarative validators, BC4J framework by default checks whether multiple rows have the same alternate key or not. If its the case, it simply throws an error, which cannot be handled programmatically.)
Primary Key attributes and Alternate Key attributes

The difference between the primary key attributes and the alternate key attributes is that, primary key attributes cannot be null and the alternate key attributes can be null.

Usage of findByAltKey method

The following is a code snippet showing how to find a row(s) using the "findByAltKey"...

Using the "findByAltKey" method from the Entity class
getEntityDef().findByAltKey(this.getDBTransaction(),"alternateKeyName",new Key(new Object[]{"",""}), false,false);
The findByAltKey in the Entity class takes 5 parameters.
  1. The current database transaction.
  2. The name of the alternate key.
  3. The Key object
  4. A boolean value which represents, whether the sub classes (inherited classes) have to be searched or not.
  5. Another boolean value which represents whether to hit the database if no row is found in the entity cache.
Using the "findByAltKey" method from the ViewObject class
findByAltKey("alternateKeyName",new Key(new Object[]{"",""}),true);
The findByAltKey in the ViewObject class takes 3 parameters
  1. The name of the alternate key
  2. The Key object
  3. A boolean value which represents a flag that controls whether, when a db query is issued to get the matching row(s), the view object's current where-clause is to be included in the query or not.

gravatar

font-size

font-size is always inherited by default, i.e every html element gets the font-size of the parent element... The following link from W3C site confirms this..
http://www.w3.org/TR/CSS2/propidx.html

font-size relative values are always relative to the font-size of the parent element.
http://www.w3.org/TR/CSS2/fonts.html#value-def-relative-size

If no font-size is specified then the default font size specified by the browser is considered(and this value can be changed by the end user)...

So setting the font-size to relative units should not cause any problems interms of accessiblity or cross browser compatability.

gravatar

Making an Entity Readonly

In BC4J all the entities that are created are updatable by default. In some cases, entities have to be readonly. To mark an entity as readonly (or non-updatable), do the following.

  • Open the Entity in the design view (i.e open the overview editor)
  • Open the property inspector
  • In the property inspector expand the "Type" tab.
  • There will be a dropdown with the label "Updatable:". Change its value to "false".

gravatar

BC4J batch update feature

This blog tells you the basic information about the batch update feature provided by the BC4J framework .

During the commit phase, BC4J framework by default executes a seperate sql statement for each entity instance that has been either updated or marked as deleted. So if there are 1000 entity instances (of an entity class) which have been either updated or marked as deleted, BC4J framework will execute 1000 appropriate sql statements.

For example, say you have an Employee entity object type for which multiple instances are modified during typical use of the application. If two instances were created, three existing instances modified, and four existing instances deleted, then at transaction commit time the framework issues nine DML statements (2 INSERTs, 3 UPDATEs, and 4 DELETEs) to save these changes.

This can lead to performance problems if the number of changes are huge and if the enity objects are changed very frequently.

To minimize the performance problem, developers need to use the batch update feature of the BC4J framework.

When the batch update feature is enabled, BC4J framework will not execute a seperate sql statement for each and every entity instance during the commit phase. Instead it performs inserts, updates and deletes in batches.

In the example, update batching (with a threshold of 1) causes the framework to issue just three DML statements: one bulk INSERT statement processing two inserts, one bulk UPDATE statement processing three updates, and one bulk DELETE statement processing four deletes.

To enable this feature the only thing that needs to be done is to select the "Use Update Batching" checkbox in the design view of all entity objects as shown below..


Also the input text box with the label "When Number of Entities to Modify Exceeds" has to be set to 1.

Batch operations mean, sending multiple insert/update/delete sql statements in one shot to the sql engine from the middle tier, instead of firing each sql statement.

This feature cannot be used under the following cases..

  • If the entity object has any attributes that are set to Refresh After Insert or Refresh After Update
  • If the Entity has any attributes of type CLOB of BLOB
  • If the entity methods related to performing DML operations, are overridden..(PL/SQL entity objects fall in this category)..

gravatar

SQL Locking basic information in oracle database

When you issue a SELECT statement against the database to query some records, no locks are placed on the selected rows . Rows are locked when the rows have been changed. This means that rows are locked when you issue a "Update" statement. In this situation (i.e when rows are locked by some user) other users will be able to read those records as they appeared before the change ..But they cannot change the contents of the locked row..

In some cases you might want to lock the rows first and then want to update the rows..For this purpose you can use the "for update" and "for update of xxxx" and "for update nowait" options..

For example..
SELECT * FROM EMP WHERE EMPNO=7654 FOR UPDATE NOWAIT

When you issue a SELECT...FOR UPDATE statement, the RDBMS automatically obtains exclusive row-level locks on all the rows identified by the SELECT statement, holding the records "for your changes only" as you move through the rows retrieved by the cursor. No one else will be able to change any of these records until you perform a ROLLBACK or a COMMIT.

This statement (SELECT....FOR UPDATE) will block the user who issued the statement , if it cannot get a lock on any of the rows. To prevent this blocking, user can use the NOWAIT option. If the "NOWAIT" option is provided, then the statement

SELECT...FOR UPDATE NOWAIT
will return an error status if it could'nt lock all the rows identified by the SELECT statement. If its able to lock all the rows, it retuns the result set containing all the rows identified by the SELECT statement and will lock all those rows.


All these locks are realeased once the user commits or rollbacks the data.


After any row is updated and committed, sql maintains information like when a row has been locked and when the lock has been released. This information can be obtained with query like..

SELECT VERSIONS_STARTTIME, VERSIONS_ENDTIME,VERSIONS_XID,
EMPNO FROM EMP VERSIONS BETWEEN TIMESTAMP SYSTIMESTAMP - INTERVAL '10' MINUTE AND SYSTIMESTAMP

You can find this information only after committing the data..