I believe I must have something configured incorrectly, or I misunderstand
transaction management performed by the container. Though I have my datasource
declared as local-tx, which I believe allows transactions, it appears that my a
call to a remote function in a stateless session bean is completely executed in
one single transaction, regardless of the @TransactionAttribute tags.
In my example, I call a function with @TransactionAttribute = REQUIRED. This
is the OUTER FUNCTION. This function inserts a record into the cust table of
our database. Then this function calls a second function with
@TransactionAttribute = REQUIRES_NEW. This is the INNER FUNCTION.
This function should, according to spec, start up a new transaction independant
of the first function. However, the INNER function can select the
(un-committed) cust record from the OUTER function. The INNER function then
proceeds to add a cust record of its own to the database.
Control then returns to the OUTER function, which can succesfully read the cust
record inserted by the INNER function, which is to be expected because the
INNER function should have had its transaction committed. However, my program
then throws a RuntimeException in order to force a rollback, and this rollback
removes both the cust record inserted by the OUTER function and the cust record
inserted by the INNER function.
To further my belief that the transaction manager is ignoring my
@TransactionAttribute annotations, I change the TransactionAttributeType of the
INNER function to "NEVER". According to spec, the code should throw an
exception when this function is called within a managed transaction. However,
when I run the code I get the exact same behavior as when the INNER function is
"REQUIRES_NEW".
I would greatly appreciate if anyone has any insight into what I am doing
wrong. Thanks!
Client Program that Invokes TestTransImpl Stateless Session Bean
------------------------------------------------------------------------------------
public class Client{
|
| public static void main(String[] args) throws Exception {
| try{
| Properties env = new Properties();
| env.setProperty(Context.SECURITY_PRINCIPAL,
"guest");
| env.setProperty(Context.SECURITY_CREDENTIALS,
"guest123");
| env.setProperty(Context.PROVIDER_URL,
"jnp://localhost:1099");
| env.setProperty(Context.URL_PKG_PREFIXES,
"org.jboss.naming:org.jnp.interfaces");
| env.setProperty(Context.INITIAL_CONTEXT_FACTORY,
"org.jboss.security.jndi.JndiLoginInitialContextFactory");
|
| InitialContext ctx = new InitialContext(env);
| TestTransRemote ttr =
(TestTransRemote)ctx.lookup("TestTransImpl/remote");
| ttr.testTransactions();
|
|
| }catch(Exception e){
| e.printStackTrace();
| throw e;
| }
|
| }
| }
Remote Interface for TestTransImpl Stateless Session Bean
--------------------------------------------------------------------------------
public interface TestTransRemote extends Serializable {
| public void testTransactions() throws Exception;
| }
TestTransImpl Stateless Session Bean
---------------------------------------------------------------------------------
@Stateless
| @Remote(TestTransRemote.class)
| public class TestTransImpl implements TestTransRemote {
| private static final long serialVersionUID = 1L;
|
| @TransactionAttribute(TransactionAttributeType.REQUIRED)
| public void testTransactions() throws Exception{
| java.sql.Connection conn = getConnection();
| java.sql.PreparedStatement ps;
|
| ps = conn.prepareCall("insert into cust(loc,cust_no) values
('001',20)");
| ps.execute();
| System.out.println("OUTSIDE FUNCTION - Customer 20 created");
|
| requiredNewFunction();
|
| ps = conn.prepareCall("Select cust_no from cust where loc =
'001' and cust_no = 24");
| java.sql.ResultSet results = ps.executeQuery();
| results.next();
| System.out.println("OUTSIDE FUNCTION - Customer Read - Cust No
= " + results.getLong("cust_no"));
|
| throw new RuntimeException();
| }
|
| @TransactionAttribute(TransactionAttributeType.REQUIRES_NEW)
| private void requiredNewFunction() throws Exception{
| java.sql.Connection conn = getConnection();
| java.sql.PreparedStatement ps;
|
| ps = conn.prepareCall("Select cust_no from cust where loc =
'001' and cust_no = 20");
| java.sql.ResultSet results = ps.executeQuery();
| results.next();
| System.out.println("INSIDE FUNCTION - Customer Read - Cust No =
" + results.getLong("cust_no"));
|
| ps = conn.prepareCall("insert into cust(loc,cust_no) values
('001',24)");
| ps.execute();
| System.out.println("INSIDE FUNCTION - Customer 24 created");
| }
|
| private java.sql.Connection getConnection() throws Exception{
| javax.sql.DataSource ds;
| javax.naming.InitialContext ic = new
javax.naming.InitialContext();
| ds = (javax.sql.DataSource)ic.lookup("java:MyOracleDS");
| java.sql.Connection conn = ds.getConnection();
| return conn;
| }
| }
Datasource XML File
--------------------------------------------------------------------------------
<?xml version="1.0" encoding="UTF-8"?>
| <datasources>
| <local-tx-datasource>
| <jndi-name>MyOracleDS</jndi-name>
| <connection-url>jdbc:oracle:thin:XXXXX(DB Host):1521:XXXXX(DB
Sid)</connection-url>
| <driver-class>oracle.jdbc.driver.OracleDriver</driver-class>
|
| <user-name>XXXXX(username)</user-name>
| <password>XXXXX(password)</password>
|
| <min-pool-size>5</min-pool-size>
| <max-pool-size>100</max-pool-size>
|
|
<exception-sorter-class-name>org.jboss.resource.adapter.jdbc.vendor.OracleExceptionSorter</exception-sorter-class-name>
|
| <!-- corresponding type-mapping in the standardjbosscmp-jdbc.xml
(optional) -->
| <metadata>
| <type-mapping>Oracle10g</type-mapping>
| </metadata>
| </local-tx-datasource>
| </datasources>
|
Program Output
-------------------------------------------------------------------------------
08:43:41,093 INFO [STDOUT] OUTSIDE FUNCTION - Customer 20 created
| 08:43:41,125 INFO [STDOUT] INSIDE FUNCTION - Customer Read - Cust No = 20
| 08:43:41,140 INFO [STDOUT] INSIDE FUNCTION - Customer 24 created
| 08:43:41,140 INFO [STDOUT] OUTSIDE FUNCTION - Customer Read - Cust No = 24
View the original post :
http://www.jboss.com/index.html?module=bb&op=viewtopic&p=3970358#3970358
Reply to the post :
http://www.jboss.com/index.html?module=bb&op=posting&mode=reply&p=3970358
_______________________________________________
jboss-user mailing list
[email protected]
https://lists.jboss.org/mailman/listinfo/jboss-user