ApplicationException - Java - Hibernate - rollback related

My question is related to Transactions and Exceptions

Requirements:

I have 10 records to insert into database table. And after inserting every record, I insert data into another table. So if inserting to second table fails, I want to rollback that record.

Ex. Say handle cash transfer (from one account to account) for 10 persons at a time.

pseudo code: ------------- Start of EJB method

for(int i = 0; i < TransferRecords.length; i++)
{
    try
    {
          //Deduct cash from TransferRecord.accountFrom --- Includes use of Hibernate Session
          //Add cash in TransferRecord.accountTo -- Includes use of Hibernate Session
     } catch(AppException exception)
     {
            //Rollback the transaction only for this particular transfer (i)
            // But here when I go for next record it says session is closed
     }
}

---------End of EJB method

Here AppException is created with @ApplicaitonException(rollback=true) annotion.

The functionality we want is: Even if the transaction fails for TransferRecord (say 2), I want the data to be committed for record 0, record 1, record 3, record 4 (etc... and but not for record 2)

But the issue here is: when TransferRecord 2 fails and when I move to TransferRecord 3, I get "Session Closed" error.

My doubts are: 1. Is this a right approach? or should I run the for loop(for each TransferRecord) outside of the EJB 2. How can I make sure that session is not closed but transaction is rolled back (only for that for particular failed transaction)

Thank you in advance.

I am using EJB3, Hibernate 3.x, Jboss 4.2.x and I am using Container Managed Transaction.

Answers


Is this a right approach?

No, with CMT, you method is your transactional unit. So here, all your TransferRecord and handled in a same and unique transaction.

By the way, how do you rollback the transaction? Do you propagate a RuntimeException or do you call setRollbackOnly()? I'm just curious.

Or should I run the for loop (for each TransferRecord) outside of the EJB?

Why outside? Nothing forces you to do that. If you want to process each TransferRecord in its own transaction, you should pass them to another EJB method (the code below is inspired by this answer):

// supposing processRecords is defined on MyStatelessRemote1 and process defined on MyStatelessLocal1
@Stateless
@TransationAttribute(TransactionAttributeType.NOT_SUPPORTED)
public class MyStatelessBean1 implements MyStatelessLocal1, MyStatelessRemote1 {
    @EJB
    private MyStatelessLocal1 myBean;

    public void processRecords(List<TransferRecord> objs) {
        // No transactional stuff so no need for a transaction here
        for(Object obj : objs) {
            this.myBean.process(obj);
        }
    }

    @TransationAttribute(TransactionAttributeType.REQUIRES_NEW)
    public void process(TransferRecord transferRecord) {
        // Transactional stuff performed in its own transaction
        // ...
    }
}

How can I make sure that session is not closed but transaction is rolled back (only for that for particular failed transaction)

I think I covered that part.


Need Your Help

Android App freezing on second launch

android dialog webview cocos2d-iphone launch

I'm developing a game for android, and I've been trying to implement a dialog to show a webview for web banner ads. (I'm using cocos2d for my development). Im using the static method ads() to open ...

Progress bar Start and Stop on Button Click using thread

c# progress-bar

I have created a C# windows application in that I inserted the progress bar.

About UNIX Resources Network

Original, collect and organize Developers related documents, information and materials, contains jQuery, Html, CSS, MySQL, .NET, ASP.NET, SQL, objective-c, iPhone, Ruby on Rails, C, SQL Server, Ruby, Arrays, Regex, ASP.NET MVC, WPF, XML, Ajax, DataBase, and so on.