0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Spring FrameworkのトランザクションをLibertyでためす

Posted at

目的

LibertyのSpring Framework 環境を構築して HelloWorld のような簡単なプログラムでテストします。

Spring プログラムの説明

Eclipse で必要な ソースコードとXMLを用意するところからの説明です。

SomeBean.java

ここで

SomeBean.java
package pdprof.spring.transaction;

import org.springframework.transaction.TransactionDefinition;
import org.springframework.transaction.TransactionException;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.jta.WebSphereUowTransactionManager;
import org.springframework.transaction.support.DefaultTransactionDefinition;

public class SomeBean {

	WebSphereUowTransactionManager transactionManager;

	public WebSphereUowTransactionManager getTransactionManager() {
		return transactionManager;
	}

	public void setTransactionManager(WebSphereUowTransactionManager transactionManager) {
		this.transactionManager = transactionManager;
	}

	@Transactional
	public void testAnnotation() {
		System.out.println("Some testAnnotation()");
	}
	
	public void test() {

		try {
			DefaultTransactionDefinition def = new DefaultTransactionDefinition();
			def.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRES_NEW);
			TransactionStatus status = transactionManager.getTransaction(def);
			System.out.println("Is the transaction new ? " + status.isNewTransaction());
			transactionManager.commit(status);

		} catch (TransactionException e) {
			e.printStackTrace();
		}

		System.out.println("Some test()");
	}
}

application-context.xml

  • SomeBean.java から使用される内容を指定する
application-context.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:context="http://www.springframework.org/schema/context"
    xmlns:tx="http://www.springframework.org/schema/tx"
    xmlns:jpa="http://www.springframework.org/schema/data/jpa"
    xmlns:aop="http://www.springframework.org/schema/aop"
    xmlns:util="http://www.springframework.org/schema/util"
    xmlns:p="http://www.springframework.org/schema/p"
    xsi:schemaLocation="http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.1.xsd
        http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd
        http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.1.xsd
        http://www.springframework.org/schema/data/jpa http://www.springframework.org/schema/data/jpa/spring-jpa-1.8.xsd
        http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.0.xsd
        http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-4.1.xsd">
	
	<tx:jta-transaction-manager/>
	<tx:annotation-driven/>
	<bean id="transactionManager"
		class="org.springframework.transaction.jta.WebSphereUowTransactionManager">
	</bean>

	<bean id="someBean" class="pdprof.spring.transaction.SomeBean">
		<property name="transactionManager">
			<ref bean="transactionManager" />
		</property>
	</bean>
</beans>

ApplicationContext の初期化

  • ApplicationContext を application-context.xml を読み込んで初期化
  • サーブレット実行時に test(), testAnnotation() メソッドを実行してトランザクションをテスト
SpringTransactionServlet.java
package pdprof.spring.transaction;

import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

/**
 * Servlet implementation class SpringTransactionServlet
 */
@WebServlet("/transaction")
public class SpringTransactionServlet extends HttpServlet {
	private static final long serialVersionUID = 1L;

	/**
	 * Default constructor.
	 */
	public SpringTransactionServlet() {
		// TODO Auto-generated constructor stub
	}

	/**
	 * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse
	 *      response)
	 */
	protected void doGet(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		test();
		response.getWriter().append("Served at: ").append(request.getContextPath());
	}

	/**
	 * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse
	 *      response)
	 */
	protected void doPost(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		doGet(request, response);
	}

	public void test() {

		ApplicationContext context = new ClassPathXmlApplicationContext("/META-INF/application-context.xml");
		SomeBean bean = (SomeBean) context.getBean("someBean");
		bean.test();
		bean.testAnnotation();

	}

}

Libertyテスト環境

これまでの方法で既存環境に構成は可能ですが、環境をdockerで用意する方法です。

今回は tWAS でも動作するように、Java8, jsp-2.3, jpa-2.2 で動かします。
server 構成は以下になります。

server.xml
<server description="new server">

    <!-- Enable features -->
    <featureManager>
        <feature>jsp-2.3</feature>
        <feature>jdbc-4.2</feature>
        <feature>cdi-2.0</feature>
        <feature>jpa-2.2</feature>
        <feature>localConnector-1.0</feature>
        <feature>eventLogging-1.0</feature>
        <feature>requestTiming-1.0</feature>
    </featureManager>

    <httpAccessLogging id="pdprofAccessLogging" logFormat="%h %u %t &quot;%r&quot; %s %b %{remote}p %D %{JSESSIONID}C %{Set-Cookie}o"/>
    <httpEndpoint accessLoggingRef="pdprofAccessLogging" host="*" httpPort="9080" httpsPort="9443" id="defaultHttpEndpoint"/>

    <eventLogging logMode="entryExit" minDuration="1ms"/>

    <requestTiming slowRequestThreshold="5s" hungRequestThreshold="10m">
    </requestTiming>

    <logging  traceSpecification="TransactionSummary=all"
      traceFileName="trace.log"
      maxFileSize="20"
      maxFiles="10"
      traceFormat="BASIC" />

   <basicRegistry id="basic">
      <user name="wsadmin" password="passw0rd" />
      <user name="reader" password="passw0rd" />
   </basicRegistry>
   <administrator-role>
      <user>wsadmin</user>
   </administrator-role>
   <reader-role>
      <user>reader</user>
   </reader-role>
    <!-- Automatically expand WAR files and EAR files -->
    <applicationManager autoExpand="true"/>

    <!-- Default SSL configuration enables trust for default certificates from the Java runtime --> 
    <ssl id="defaultSSLConfig" trustDefaultCerts="true"/>

    <applicationMonitor updateTrigger="mbean"/>

    <webApplication id="spring.transaction" location="spring.transaction.war" name="spring.transaction"/>
</server>

Libertyテスト環境の自動構築

これまでの方法で既存環境に構成は可能ですが、環境をdockerで用意する方法です。

用意したGitレポジトリをクローンします。

git clone http://github.com/pdprof/spring-transaction.git
cd spring-transaction/spring-transaction-docker

Libertyのイメージをビルドして開始します。

./setup-docker.sh
./start.sh

Libertyの起動を確認します。SpringTransactionServlet にアクセスします。

image.png

と表示されれば問題ありません。

トランザクション処理を確認

docker container にアクセスしてtrace.logでトランザクションを確認します。

podman exec -it spring-transaction bash
more /logs/trace.log

getTransaction() でトランザクション開始

org.springframework.transaction.support.AbstractPlatformTransactionManager.getTransaction(AbstractPlatformTransactionManager.java:373)

の呼び出しが確認できます。

4/29/25 15:01:52:648 UTC] 00000033 TransactionIm 3   Transaction created. 
                                 com.ibm.tx.jta.embeddable.impl.EmbeddableTransactionImpl@a8adf6fe#tid=138827292,active=0,suspended=0,Not on a thread,gtrid=0000019682119585000000010846561c88a9e4b2aacda5c60ff4e6ce705569cfddc6e538
                                 {XidImpl: formatId(57415344), gtrid_length(36), bqual_length(40),
data(0000019682119585000000010846561c88a9e4b2aacda5c60ff4e6ce705569cfddc6e5380000019682119585000000010846561c88a9e4b2aacda5c60ff4e6ce705569cfddc6e53800000001)}
 trace                           java.lang.Throwable: Transaction creation stack--More--(41%)
	at com.ibm.tx.jta.impl.TransactionImpl.traceCreate(TransactionImpl.java:3383)
	at com.ibm.tx.jta.impl.TransactionImpl.<init>(TransactionImpl.java:334)
	at com.ibm.tx.jta.embeddable.impl.EmbeddableTransactionImpl.<init>(EmbeddableTransactionImpl.java:89)
	at com.ibm.tx.jta.embeddable.impl.EmbeddableTranManagerImpl.createNewTransaction(EmbeddableTranManagerImpl.java:78)
	at com.ibm.tx.jta.embeddable.impl.EmbeddableTranManagerImpl.createNewTransaction(EmbeddableTranManagerImpl.java:30)
	at com.ibm.tx.jta.impl.TranManagerImpl.beginUserTran(TranManagerImpl.java:124)
	at com.ibm.tx.jta.impl.TranManagerSet.beginUserTran(TranManagerSet.java:107)
	at com.ibm.tx.jta.impl.UserTransactionImpl.begin(UserTransactionImpl.java:66)
	at com.ibm.tx.jta.embeddable.impl.EmbeddableUserTransactionImpl.begin(EmbeddableUserTransactionImpl.java:71)
	at com.ibm.ws.transaction.services.UserTransactionService.begin(UserTransactionService.java:68)
	at org.springframework.transaction.jta.JtaTransactionManager.doJtaBegin(JtaTransactionManager.java:886)
TransactionManager.java:849)rk.transaction.jta.JtaTransactionManager.doBegin(Jta--More--(48%)
	at org.springframework.transaction.support.AbstractPlatformTransactionManager.startTransaction(AbstractPlatformTransactionManager.java:400)
	at org.springframework.transaction.support.AbstractPlatformTransactionManager.getTransaction(AbstractPlatformTransactionManager.java:373)
	at pdprof.spring.transaction.SomeBean.test(SomeBean.java:32)
	at pdprof.spring.transaction.SomeBean$$FastClassBySpringCGLIB$$b1dba14.invoke(<generated>)
	at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:218)
	at org.springframework.aop.framework.CglibAopProxy.invokeMethod(CglibAopProxy.java:386)
	at org.springframework.aop.framework.CglibAopProxy.access$000(CglibAopProxy.java:85)
	at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:703)
	at pdprof.spring.transaction.SomeBean$$EnhancerBySpringCGLIB$$bd4c84c6.test(<generated>)
	at pdprof.spring.transaction.SpringTransactionServlet.test(SpringTransactionServlet.java:50)
	at pdprof.spring.transaction.SpringTransactionServlet.doGet(SpringTransactionServlet.java:33)
	at javax.servlet.http.HttpServlet.service(HttpServlet.java:686)
        at javax.servlet.http.HttpServlet.service(HttpServlet.java:791)

@Transactional でのトランザクション開始

<tx:annotation-driven/><bean id="transactionManager" ../> の指定で

org.springframework.transaction.jta.WebSphereUowTransactionManager.execute(WebSphereUowTransactionManager.java:306)

が実行されています。トレースが出力されていることでLibertyのトランザクションマネージャーが使われていることが分かります。

[4/29/25 15:01:52:660 UTC] 00000033 TransactionIm 3   Transaction created. 
                                 com.ibm.tx.jta.embeddable.impl.EmbeddableTransactionImpl@fd6d3e5b#tid=138827300,active=0,suspended=0,Not on a thread,gtrid=0000019682119594000000010846562488a9e4b2aacda5c60ff4e6ce705569cfddc6e538
                                 {XidImpl: formatId(57415344), gtrid_length(36), bqual_length(40),
data(0000019682119594000000010846562488a9e4b2aacda5c60ff4e6ce705569cfddc6e5380000019682119594000000010846562488a9e4b2aacda5c60ff4e6ce705569cfddc6e53800000001)}
                                 java.lang.Throwable: Transaction creation stack trace
	at com.ibm.tx.jta.impl.TransactionImpl.traceCreate(TransactionImpl.java:3383)
	at com.ibm.tx.jta.impl.TransactionImpl.<init>(TransactionImpl.java:334)
	at com.ibm.tx.jta.embeddable.impl.EmbeddableTransactionImpl.<init>(EmbeddableTransactionImpl.java:89)
nsaction(EmbeddableTranManagerImpl.java:78)mbeddableTranManagerImpl.createNewTra--More--(74%)
	at com.ibm.tx.jta.embeddable.impl.EmbeddableTranManagerImpl.createNewTransaction(EmbeddableTranManagerImpl.java:30)
	at com.ibm.tx.jta.impl.TranManagerImpl.beginUserTran(TranManagerImpl.java:124)
	at com.ibm.tx.jta.impl.TranManagerSet.beginUserTran(TranManagerSet.java:107)
	at com.ibm.tx.jta.impl.UserTransactionImpl.begin(UserTransactionImpl.java:66)
	at com.ibm.ws.uow.embeddable.EmbeddableUOWManagerImpl.uowBegin(EmbeddableUOWManagerImpl.java:885)
	at com.ibm.ws.uow.embeddable.EmbeddableUOWManagerImpl.runUnderNewUOW(EmbeddableUOWManagerImpl.java:727)
	at com.ibm.ws.uow.embeddable.EmbeddableUOWManagerImpl.runUnderUOW(EmbeddableUOWManagerImpl.java:331)
	at org.springframework.transaction.jta.WebSphereUowTransactionManager.execute(WebSphereUowTransactionManager.java:306)
	at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:417)
	at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:119)
	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
        at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:762)
	at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:707)
	at pdprof.spring.transaction.SomeBean$$EnhancerBySpringCGLIB$$bd4c84c6.testAnnotation(<generated>)
	at pdprof.spring.transaction.SpringTransactionServlet.test(SpringTransactionServlet.java:51)
	at pdprof.spring.transaction.SpringTransactionServlet.doGet(SpringTransactionServlet.java:33)
	at javax.servlet.http.HttpServlet.service(HttpServlet.java:686)
	at javax.servlet.http.HttpServlet.service(HttpServlet.java:791)


トラブルシューティング

毎度のことですが、よくつかう dockerコマンドを書いておきます。この文書でもpodman, dockerとまとまりがないですが、Linux では dockerがpodmanを呼び出すようになっていました。

docker ps # 動作中のContainer確認
docker logs -f spring-transaction # ログ確認
docker restart spring-transaction # 再起動
docker inspect spring-transaction # container 確認
docker exec -it spring-transaction bash # Container内状況確認

まとめ

Libertyの環境を構築して、Spring Framework のトランザクションをテストしました。

参考

以下ページを参考にさせていただきました。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?