Sunday, January 12, 2014

Boost performance JAVA EJB

Using EJB (entity java beans) for enterprise client server application may be a good idea.
but it is highly important to divide your code into many EJB's as you can , for each EJB class being responsible for its logical functionality.  

But doing the above can result in a performance issue , because jumping and calling many time to the EJB server from the client code takes time.

for example having this EJB:

@remote
MyEjb
..
..
public List<Object> getObject1()
{
return new ArrayList<Object>();
}

public List<Object> getObject1()
{
return new ArrayList<Object>();
}


Client code:

public static void main (String []args)
{
List<Object> list1 = MyEjb.getObject1();
List<Object> list2 = MyEjb.getObject1();
}
we have here 2 calling and to the EJB server. which takes time....
and time is something that we want to save.

A Much better option would be:

@remote
MyEjb
..
..
public Pair<List<Object>,List<Object>> getObjects()
{
return new Pair<List<Object>,List<Object>>( new ArrayList<Object>,  new ArrayList<Object>);
}

Client code:

public static void main (String []args)
{
Pair pair = MyEjb.getObjects();
//and then retrieve the data from the pair.
}

this is a better option!!

*please note: this is a sample code , calling the EJB server must be done via the interface.

Monday, January 6, 2014

Hibernate updating rows when selecting?


Assume you have an entity that is mapped to your db with Hibernate.
when you are trying only to select this entity , you see many update sentences running in your server console.
this is a very bad thing because update may take time and to result in unwanted behavior.
please note that the updates are actually meaningless because they update the same value over and over again.

your console may result in:
select * ... from EMP
{10 rows being selected}
update  EMP set ..
update  EMP set ..
update  EMP set ..
.
.
.
10 times.
this is happening because your entity has logic of different filed in the setter.
for example:
class EMP
{
mapped..
 int a;

int b ;

getA()
grtB()

setA()
setB()
{
 setA(something);
}

because the B filed has logic with the A filed ,in B's setter the problem occurs.
this is happening because hibernate loads data into setters when performing select , and then thjins that the entity has changed because of the setB().
to fix it : remove the extra logic on A field from setB().

Sunday, January 5, 2014

What is a transaction?

When you log into your database (with sqlplus or any other DB tool), you assign to a Session.
For each log in, a new session will be created.

On that session you can make your DML and DDL commands, and that session is private for the user logged in.

Oracle, and some other DBs, work in a transaction-based mode.
A transaction is a set of DML commands that hasn't been executed for the entire DB but only for the user's session.
To close a transaction you use either -
COMMIT: for saying - OK, I want those changes
ROLLBACK: for omitting the changes on the data.

This allows you to perform multiple DML commands and preview the result in your private session before publishing it.

A session can have only one active transaction (See more here) and a rule of thumb says that you should not leave an open transaction. Every command (or commands set) should be finished with a Commit or Rollback.

Oracle works in a 'Rollback segment' method which is very important to understand:

When a session performs a DML, the data is being changed on the table! It doesn't wait for a commit.
But it marks those affected rows with a flag means they are not updated.
The opposite command is being saved as well.
Lets say we Inserted 30 rows, those rows has been actually inserted into the table, and a 30-rows-delete-clause has been created.

When the transaction is still open, and other sessions query that data, oracle will perform that reverse command and show those sessions that data BEFORE that change.

After a commit, those affected rows are marked as updated and the transaction is terminate.
After a rollback, on the other hand, Oracle will use the reverse script to "fix" the non-wanted rows.

Now you can understand several things:

1) Why Commit takes zero time (Oracle thought that commit is more common than rollback).
2) Why Rollback takes a lot of time.
3) Why deleting a large amount of rows without using commit each 100 rows is a bad thing.
4) Why leaving an open transaction can cause problems.




Autonomous Transactions

There are cases when you have to run a large script, that will influence your data (DML Only) but the situation of half work is impossible due to data consistency.

In Oracle it's very easy because when you make a change in your data (Insert, Update, Delete, Merge), Oracle will create a new transaction.
The changes will be limited to your session only (Read more in our Transaction post).

After running the first DML command, the following DMLs will stack in that transaction created for the first command, and all the changes are local in your session.

Transaction is terminate whether a Commit Or a Rollback is execute.
(DDL commands Commit the transaction).


Getting back to our script, This format is suitable:


BEGIN
<DML Command>
<DML Command>
<DML Command>
<DML Command>
<DML Command>
<DML Command>

COMMIT;

EXCEPTION WHEN OTHERS THEN
     ROLLBACK;
END;


This will ensure the script will either run completely or not at all.
But what if we want to keep track on the script? and report to a log table for each successful DML? (For example- how many rows were affected).
Ofcourse we can use the dopl (dbms_output.print_line()) and write directly to the console,  but that is too temporary.

Let's create a new Table for logging our script:


CREATE TABLE script_log (execute_time DATE,
                         dml_name VARCHAR2(100));


And now, we'll just insert the information to the log table.

Can you see the problem?
This insertion to the log table is a DML command itself, therefore it will be roll-backed each time an error occurred somewhere in the script and we lost the information.

We want a mechanism that allows us to use Commit on certain commands.

And thankfully Oracle supply this kind of mechanism  called - Autonomous Transaction.
This transaction is a child transaction of the original one, and can be committed without effecting the host transaction.
You can easily create a pl/sql paragraph that is autonomous like that:

DECLARE
  PRAGMA AUTONOMOUS_TRANSACTION;
BEGIN
    INSERT INTO sciprt_log(execute_time, dml_name)
    VALUES (sysdate, 'Insert into Employees');
  COMMIT;
END;


Or even create an autonomous function/procedure but remember that- an autonomous section has to end either with a commit or a rollback clause. You can leave that transaction open!

Good luck!