geronimo-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "Ivan Dubrov (JIRA)" <...@geronimo.apache.org>
Subject [jira] Updated: (GERONIMO-724) Nested transactions do not work correctly
Date Thu, 07 Jul 2005 05:42:11 GMT
     [ http://issues.apache.org/jira/browse/GERONIMO-724?page=all ]

Ivan Dubrov updated GERONIMO-724:
---------------------------------

    Description: 
I have the following code in my business logic EJB stateless bean:

// Create User entity and Account entity
UserLocal user = userHome.create(group, data);
AccountLocal account = accountHome.create(user);

This is the ejbCreate and ejbPostCreate for the Account EJB:

public Long ejbCreate(UserLocal user) {
    try {
        Long id = new Long(IdGeneratorUtil.getHome().create().generateId());
        setId(id);
        return id;
    } catch (Exception e) {
        throw new EJBException(e);
    }
}
	
public void ejbPostCreate(UserLocal user) {
    setUser(user); // Set reference to the User entity
}

This is the snippet from the DDL, note that account references the USERS table:

CREATE TABLE ACCOUNTS (
	ACCOUNT_ID BIGINT NOT NULL PRIMARY KEY,
	USER_ID BIGINT REFERENCES USERS(USER_ID),
       ...
);


The IdGenerator is the standard EJB pattern for generating identifiers - Entity with counter
behind Session. I have the following trasnactions attributes (TA):

All entities (User and Account) have TA = "Mandatory".
Business logic (that creates Users and Accounts) EJB has TA = "Required"
IdGenerator EJB have TA = "RequiresNew", so the identifier is generated in the nested transaction.

This should work, since creation of both entities is done in single transaction (that is suspended
several times when identifier generation is invoked). So, this transaction contains two database
inserts - for User and for Account. Since both rows should be commited at once, the reference
in the Account table is satisfied.

But I get the exception (sometimes, sometimes it just works)). Here is the snippet from it:

Caused by: SQL Exception: INSERT on table 'ACCOUNTS' caused a violation of foreign key constraint
'SQL050705051513661' for key (72).  The statement has been rolled back.
        at org.apache.derby.impl.jdbc.Util.generateCsSQLException(Util.java)
        at org.apache.derby.impl.jdbc.TransactionResourceImpl.wrapInSQLException(TransactionResourceImpl.java)

It looks like the row into the ACCOUNTS table is inserted (and commited) not in the same transaction
as row inserted into the USERS table, and even before the row inserted (and commited) into
the USERS.

If I change transaction attribute for the IdGenerator stateless bean from RequiresNew to Required
everything it alway works, so the problem seems like due to the nested transactions (maybe,
the Account creation is associated with incorrect transaction)



  was:
I have the following code in my business logic EJB stateless bean:

// Create User entity and Account entity
UserLocal user = userHome.create(group, data);
AccountLocal account = accountHome.create(user);

This is the ejbCreate and ejbPostCreate for the Account EJB:

public Long ejbCreate(UserLocal user) {
    try {
        Long id = new Long(IdGeneratorUtil.getHome().create().generateId());
        setId(id);
        return id;
    } catch (Exception e) {
        throw new EJBException(e);
    }
}
	
public void ejbPostCreate(UserLocal user) {
    setUser(user); // Set reference to the User entity
}

This is the snippet from the DDL, note that account references the USERS table:

CREATE TABLE ACCOUNTS (
	ACCOUNT_ID BIGINT NOT NULL PRIMARY KEY,
	USER_ID BIGINT REFERENCES USERS(USER_ID),
       ...
);


The IdGenerator is the standard EJB pattern for generating identifiers - Entity with counter
behind Session. I have the following trasnactions attributes (TA):

All entities (User and Account) have TA = "Mandatory".
Business logic (that creates Users and Accounts) EJB has TA = "Required"
IdGenerator EJB have TA = "RequiresNew", so the identifier is generated in the nested transaction.

This should work, since creation of both entities is done in single transaction (that is suspended
several times when identifier generation is invoked). So, this transaction contains two database
inserts - for User and for Account. Since both rows should be commited at once, the reference
in the Account table is satisfied.

But I get the exception (sometimes, sometimes it just works)). Here is the snippet from it:

Caused by: SQL Exception: INSERT on table 'ACCOUNTS' caused a violation of foreign key constraint
'SQL050705051513661' for key (72).  The statement has been rolled back.
        at org.apache.derby.impl.jdbc.Util.generateCsSQLException(Util.java)
        at org.apache.derby.impl.jdbc.TransactionResourceImpl.wrapInSQLException(TransactionResourceImpl.java)

It looks like the row into the ACCOUNTS table is inserted (and commited) not in the same transaction
as row inserted into the USERS table, and even before the row inserted (and commited) into
the USERS.

If I change transaction attribute for the IdGenerator stateless bean from RequiresNew to Required
everything it alway works, so the problem seems like due to the nested transactions (maybe,
)




> Nested transactions do not work correctly
> -----------------------------------------
>
>          Key: GERONIMO-724
>          URL: http://issues.apache.org/jira/browse/GERONIMO-724
>      Project: Geronimo
>         Type: Bug
>   Components: transaction manager
>     Versions: 1.0-M4
>  Environment: Geronimo snapshot built on the 2005/06/30
> Embedded Derby
>     Reporter: Ivan Dubrov
>     Priority: Critical

>
> I have the following code in my business logic EJB stateless bean:
> // Create User entity and Account entity
> UserLocal user = userHome.create(group, data);
> AccountLocal account = accountHome.create(user);
> This is the ejbCreate and ejbPostCreate for the Account EJB:
> public Long ejbCreate(UserLocal user) {
>     try {
>         Long id = new Long(IdGeneratorUtil.getHome().create().generateId());
>         setId(id);
>         return id;
>     } catch (Exception e) {
>         throw new EJBException(e);
>     }
> }
> 	
> public void ejbPostCreate(UserLocal user) {
>     setUser(user); // Set reference to the User entity
> }
> This is the snippet from the DDL, note that account references the USERS table:
> CREATE TABLE ACCOUNTS (
> 	ACCOUNT_ID BIGINT NOT NULL PRIMARY KEY,
> 	USER_ID BIGINT REFERENCES USERS(USER_ID),
>        ...
> );
> The IdGenerator is the standard EJB pattern for generating identifiers - Entity with
counter behind Session. I have the following trasnactions attributes (TA):
> All entities (User and Account) have TA = "Mandatory".
> Business logic (that creates Users and Accounts) EJB has TA = "Required"
> IdGenerator EJB have TA = "RequiresNew", so the identifier is generated in the nested
transaction.
> This should work, since creation of both entities is done in single transaction (that
is suspended several times when identifier generation is invoked). So, this transaction contains
two database inserts - for User and for Account. Since both rows should be commited at once,
the reference in the Account table is satisfied.
> But I get the exception (sometimes, sometimes it just works)). Here is the snippet from
it:
> Caused by: SQL Exception: INSERT on table 'ACCOUNTS' caused a violation of foreign key
constraint 'SQL050705051513661' for key (72).  The statement has been rolled back.
>         at org.apache.derby.impl.jdbc.Util.generateCsSQLException(Util.java)
>         at org.apache.derby.impl.jdbc.TransactionResourceImpl.wrapInSQLException(TransactionResourceImpl.java)
> It looks like the row into the ACCOUNTS table is inserted (and commited) not in the same
transaction as row inserted into the USERS table, and even before the row inserted (and commited)
into the USERS.
> If I change transaction attribute for the IdGenerator stateless bean from RequiresNew
to Required everything it alway works, so the problem seems like due to the nested transactions
(maybe, the Account creation is associated with incorrect transaction)

-- 
This message is automatically generated by JIRA.
-
If you think it was sent incorrectly contact one of the administrators:
   http://issues.apache.org/jira/secure/Administrators.jspa
-
For more information on JIRA, see:
   http://www.atlassian.com/software/jira


Mime
View raw message