<?xml version="1.0" encoding="UTF-8"?>
<document xmlns="http://maven.apache.org/XDOC/2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://maven.apache.org/XDOC/2.0 http://maven.apache.org/xsd/xdoc-2.0.xsd">
	<properties>
		<title>トランザクション</title>
	</properties>
	<body>
		<section name="目次">
			<ul>
				<li><a href="#概要">概要</a></li>
				<li><a href="#設定方法">設定方法</a></li>
				<li><a href="#利用方法">利用方法</a>
					<ul>
						<li><a href="#ローカルトランザクションの開始と終了">ローカルトランザクションの開始と終了</a></li>
						<li><a href="#セーブポイント">セーブポイント</a></li>
					</ul>
				</li>
			</ul>
		</section>
		<section name="概要">
			<p>
				Domaは、ローカルトランザクションをサポートします。このドキュメントでは、ローカルトランザクションの設定方法と利用方法について説明します。
			</p>
			<p>
				グローバルトランザクションを使用したい場合は、JTA（Java Transaction API）の実装をもつフレームワークやアプリケーションサーバーの機能を利用してください。
			</p>
			<p>
				ローカルトランザクションのサンプルは<a href="../tutorial/index.html">チュートリアル</a>を、
				JTAを使ったグローバルトランザクションのサンプルは<a href="../jpetstore.html">Doma JPetStore</a>を参照ください。
			</p>
		</section>
		<section name="設定方法">
			<p>
				ローカルトランザクションを有効にするには、データソースとして<a href ="../apidocs/org/seasar/doma/jdbc/tx/LocalTransactionalDataSource.html"><code>LocalTransactionalDataSource</code></a>を使用します。
				このクラスのインスタンスは<a href="config.html">設定クラス</a>でシングルトンとして管理し、<code>getDataSource()</code>メソッドで外部に返すようにしてください。
			</p>
			<p>
				<code>LocalTransactionalDataSource</code>の<code>getLocalTransaction(JdbcLogger)</code>メソッドは、<a href ="../apidocs/org/seasar/doma/jdbc/tx/LocalTransaction.html"><code>LocalTransaction</code></a>を生成して返します。
				このクラスのインスタンスがローカルトランザクションを表します。
				このインスタンスを外部へ返すためのメソッドを設定クラスに作成してください。
			</p>
			<p>
				ローカルトランザクションに対応した設定クラスの例は以下のとおりです。
			</p>
<source><![CDATA[public class AppConfig extends DomaAbstractConfig {

    protected static final LocalTransactionalDataSource dataSource = createDataSource();

    protected static final Dialect dialect = new HsqldbDialect();

    @Override
    public DataSource getDataSource() {
        return dataSource;
    }

    @Override
    public Dialect getDialect() {
        return dialect;
    }

    protected static LocalTransactionalDataSource createDataSource() {
        SimpleDataSource dataSource = new SimpleDataSource();
        dataSource.setUrl("jdbc:hsqldb:mem:tutorial");
        dataSource.setUser("sa");
        return new LocalTransactionalDataSource(dataSource);
    }

    public static LocalTransaction getLocalTransaction() {
        return dataSource.getLocalTransaction(defaultJdbcLogger);
    }

}]]></source>
		</section>
		<section name="利用方法">
			<p>
				設定クラスをDaoインタフェースに以下のように注釈するとして例を示します。
			</p>
<source><![CDATA[@Dao(config = AppConfig.class)
public interface EmployeeDao {
    ...
}]]></source>
			<subsection name="ローカルトランザクションの開始と終了">
				<p>
					設定クラスから<code>LocalTransactional</code>を取得し、トランザクションを<code>begin()</code>で開始し、<code>commit()</code>または<code>rollback()</code>でトランザクションを終了します。
				</p>
<source><![CDATA[LocalTransaction tx = AppConfig.getLocalTransaction();
try {
    // 開始
    tx.begin();

    Employee employee = dao.selectById(1);
    employee.setName("hoge");
    employee.setJobType(JobType.PRESIDENT);
    dao.update(employee);

    // コミット
    tx.commit();
} finally {
    // ロールバック
    tx.rollback();
}]]></source>
				<p>
					次のように記述することもできます。
				</p>
<source><![CDATA[try {
    // 開始
    AppConfig.getLocalTransaction().begin();

    Employee employee = dao.selectById(1);
    employee.setName("hoge");
    employee.setJobType(JobType.PRESIDENT);
    dao.update(employee);

    // コミット
    AppConfig.getLocalTransaction().commit();
} finally {
    // ロールバック
    AppConfig.getLocalTransaction().rollback();
}]]></source>
				<p>
					<code>begin()</code>で開始されたトランザクションは、必ず<code>commit()</code>または<code>rollback()</code>で終了しなければいけません。
					<code>LocalTransactionalDataSource</code>を利用するデータアクセスは、例外なく必ずローカルトランザクションの中で実行しなければいけません。
				</p>
				<p>
					トランザクションはトランザクション分離レベルを指定して開始することができます。
				</p>
<source><![CDATA[LocalTransaction tx = AppConfig.getLocalTransaction();
try {
    tx.begin(TransactionIsolationLevel.SERIALIZABLE);
    ...
    tx.commit();
} finally {
    tx.rollback();
}]]></source>
			</subsection>
			<subsection name="セーブポイント">
				<p>
					セーブポイントを使用することで、トランザクション中の特定の変更を取り消すことができます。
				</p>
<source><![CDATA[LocalTransaction tx = AppConfig.getLocalTransaction();
try {
    tx.begin();

    // 検索して更新
    Employee employee = dao.selectById(1);
    employee.setName("hoge");
    dao.update(employee);

    // セーブポイントを作成
    tx.setSavepoint("beforeDelete");

    // 削除
    dao.delete(employee);

    // セーブポイントへ戻る（上で行った削除を取り消す）
    tx.rollback("beforeDelete");

    tx.commit();
} finally {
    tx.rollback();
}]]></source>
			</subsection>
		</section>
	</body>
</document>