Откат не работает с Tomcat, используя JOTM
Я использовал oc4j для разработки веб-приложения с использованием JSP, сервлетов и JDBC (dayabase: oracle 11gr2). Использовал встроенный менеджер транзакций, а коммиты и откаты работали нормально.
Однако из-за лицензирования мы теперь должны перенести код на бесплатный сервер, такой как tomcat. Я реализовал JOTM в качестве менеджера транзакций в Tomcat, следуя инструкциям в этом посте:
http://codepitbull.wordpress.com/2011/07/08/tomcat-7-with-full-jta/
Ниже приведена конфигурация в%CATALINA_HOME%/conf/context.xml.
<Resource name="jdbc/ticketds"
auth="Container"
type="javax.sql.DataSource"
factory="org.apache.tomcat.jdbc.pool.DataSourceFactory"
validationQuery="SELECT 1"
maxActive="30"
minIdle="2"
maxWait="10000"
initialSize="10"
defaultAutoCommit="false"
username="xxxx"
password="xxxxx"
driverClassName="oracle.jdbc.OracleDriver"
url="jdbc:oracle:thin:@//xxxxx.xxxx.com:iiii/xyz"/>
<Resource name="jdbc/taskds"
auth="Container"
type="javax.sql.DataSource"
factory="org.apache.tomcat.jdbc.pool.DataSourceFactory"
validationQuery="SELECT 1"
maxActive="30"
minIdle="2"
maxWait="10000"
initialSize="10"
defaultAutoCommit="false"
username="apps"
password="few1idna"
driverClassName="oracle.jdbc.OracleDriver"
url="jdbc:oracle:thin:@//xxxxx.xxxx.com:iiii/xyz"/>
<Transaction factory="org.objectweb.jotm.UserTransactionFactory"
jotm.timeout="600"/>
Файл web.xml настроен на упоминание источника данных в ресурсных ссылках следующим образом:
<resource-ref>
<description>Ticket Datasource configuration</description>
<res-ref-name>jdbc/ticketds</res-ref-name>
<res-type>javax.sql.DataSource</res-type>
<res-auth>Container</res-auth>
</resource-ref>
<resource-ref>
<description>SR Datasource configuration</description>
<res-ref-name>jdbc/taskds</res-ref-name>
<res-type>javax.sql.DataSource</res-type>
<res-auth>Container</res-auth>
</resource-ref>
Однако, когда я пытаюсь выполнить откат, это не помогает. Вот пример тестового кода для отката, который я использую для тестирования:
UserTransaction utx = DBUtil.getUserTransaction();
Connection conn = DBUtil.getConnection();
TicketMessageVO newTicket = null;
try {
utx.begin();
newTicket = new TicketDAO(conn).createTicket(ticket);
// testing only
if(1==1) throw new Exception("Testing transaction rollback");
utx.commit();
logger.log(Level.INFO, "Ticket created successfully: " + ticket.getMessageId());
} catch (Throwable e) {
utx.rollback();
logger.log(Level.SEVERE, "Error in creating ticket: ", e);
throw new Exception(e);
} finally {
DBUtil.closeResources(null, null, conn);
}
return newTicket;
Тот же самый фрагмент кода, который прекрасно работал с oc4j. Я что-то упустил в конфигурации?
Благодарю.
1 ответ
Недавно я столкнулся с той же проблемой и решил ее, используя собственную фабрику источников данных JOTM (org.objectweb.jotm.datasource.DataSourceFactory
) вместо Tomcat's. Вот как должен выглядеть ваш context.xml:
<Resource name="jdbc/taskds"
auth="Container"
type="javax.sql.DataSource"
factory="org.objectweb.jotm.datasource.DataSourceFactory"
validationQuery="SELECT 1"
maxActive="30"
minIdle="2"
maxWait="10000"
initialSize="10"
defaultAutoCommit="false"
username="apps"
password="few1idna"
driverClassName="oracle.jdbc.OracleDriver"
url="jdbc:oracle:thin:@//xxxxx.xxxx.com:iiii/xyz"/>
Однако использование JOTM таким образом приводит к зависанию Tomcat во время завершения работы (возможно, из-за потока, не являющегося демоном в Carol).