<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>技術ブログ &#124; 株式会社クラウディア &#187; データベース</title>
	<atom:link href="https://cloudear.jp/blog/?cat=19&#038;feed=rss2" rel="self" type="application/rss+xml" />
	<link>https://cloudear.jp/blog</link>
	<description>クラウド専門の業務システム・社内ツール開発</description>
	<lastBuildDate>Fri, 12 Nov 2021 05:00:35 +0000</lastBuildDate>
	<language>ja</language>
		<sy:updatePeriod>hourly</sy:updatePeriod>
		<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=4.0.1</generator>
	<item>
		<title>JPAを深掘りする〜Criteria APIで型安全な検索を追求しよう！【基本編】</title>
		<link>https://cloudear.jp/blog/?p=2101</link>
		<comments>https://cloudear.jp/blog/?p=2101#comments</comments>
		<pubDate>Mon, 22 Feb 2016 02:10:59 +0000</pubDate>
		<dc:creator><![CDATA[tomo]]></dc:creator>
				<category><![CDATA[Java]]></category>
		<category><![CDATA[O/Rマッパー]]></category>
		<category><![CDATA[データベース]]></category>
		<category><![CDATA[フレームワーク]]></category>
		<category><![CDATA[プログラム]]></category>

		<guid isPermaLink="false">https://cloudear.jp/blog/?p=2101</guid>
		<description><![CDATA[今回はJavaEEの中でも特に重要な「JPA（Java Persistence API）」を深掘りしてみます。基本編と応用編の２回に渡ってじっくりとJPAをご紹介します。 JPAとは JPAは一言で言えば「高機能なDBア [&#8230;]]]></description>
				<content:encoded><![CDATA[<p>今回はJavaEEの中でも特に重要な<strong>「JPA（Java Persistence API）」</strong>を深掘りしてみます。基本編と応用編の２回に渡ってじっくりとJPAをご紹介します。</p>
<h2>JPAとは</h2>
<p>JPAは一言で言えば「高機能なDBアクセスフレームワーク」です。DBアクセスフレームワークは実に様々なものがありますが、JPAの特徴は</p>
<p><span id="more-2101"></span></p>
<ul>
<li>エンティティクラスへの操作を通してDB操作を実現する（DBの都合はプログラマから極力隠される）</li>
<li>型安全を追求するための様々な機能を備える</li>
</ul>
<p>が挙げられます。Javaの良さを引き出す工夫に満ちたフレームワークと言えるでしょう。</p>
<p>様々な機能を備えたJPAですが、本エントリでは、検索、中でもCriteria APIを使った型安全な検索を中心にご紹介します。コードをしっかり載せていきますので、Criteria APIのコンセプトを感じ取っていただけると思います。</p>
<p>なお、JPAを動作させる環境を構築する方法は「<a title="JavaEEだけでここまで出来る！GlassFish+Eclipseで高速Webアプリ開発【環境構築編】" href="https://cloudear.jp/blog/?p=1375">JavaEEだけでここまでできる！GlassFish+Eclipseで高速Webアプリ開発【環境構築編】</a>」をご覧下さい。</p>
<h2>準備１・メタモデルクラスを自動生成する設定</h2>
<p>メタモデルクラスとは、エンティティクラスのプロパティに関する情報を表すクラスであり、型安全にJPAを使うためには欠かせないクラスです。</p>
<p>例えば次のようなエンティティクラスがあったとしましょう。</p>
<pre class="lang:java decode:true" title="User.java">package sandbox.entity;

import javax.persistence.Column;
import javax.persistence.Embedded;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;

@Entity
public class User {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    Long      id;

    @Column(length = 150, unique = true, nullable = false)
    String    name;

    // getter/setterは省略
}
</pre>
<p>このエンティティクラスに対するメタモデルクラスは次のようになります。</p>
<pre class="lang:java decode:true " title="User_.java">package sandbox.entity;

import javax.annotation.Generated;
import javax.persistence.metamodel.SingularAttribute;
import javax.persistence.metamodel.StaticMetamodel;

@Generated(value="Dali", date="2016-02-12T22:59:19.623+0900")
@StaticMetamodel(User.class)
public class User_ {
	public static volatile SingularAttribute&lt;User, String&gt; name;
	public static volatile SingularAttribute&lt;User, Long&gt; id;
}
</pre>
<p>メタモデルクラスはeclipseのような開発環境に自動で作ってもらうことができますので、有効にしておきましょう。</p>
<p>ecliseの場合の手順を紹介しておきます。プロジェクトのプロパティを開き、「プロジェクト・ファセット」から「Convert to faceted form&#8230;」をクリックします。</p>
<p><a href="https://cloudear.jp/blog/wp-content/uploads/2016/02/convert-to-faceted-form.png"><img class="alignnone size-full wp-image-2107" src="https://cloudear.jp/blog/wp-content/uploads/2016/02/convert-to-faceted-form.png" alt="convert-to-faceted-form" width="833" height="348" /></a></p>
<p>&nbsp;</p>
<p>プロジェクト・ファセットが有効になったので、JPAサポートを有効にします。</p>
<p><a href="https://cloudear.jp/blog/wp-content/uploads/2016/02/project-facets-jpa.png"><img class="alignnone size-full wp-image-2109" src="https://cloudear.jp/blog/wp-content/uploads/2016/02/project-facets-jpa.png" alt="project-facets-jpa" width="806" height="408" /></a></p>
<p>ここで「 OK」を押していったんプロパティ画面を閉じます。</p>
<p>再びプロパティ画面を開くと「JPA」という設定項目が増えていますので、メタモデルクラスの自動生成を有効にします。</p>
<p><a href="https://cloudear.jp/blog/wp-content/uploads/2016/02/eclipse-jpa-metamodel.png"><img class="alignnone size-full wp-image-2110" src="https://cloudear.jp/blog/wp-content/uploads/2016/02/eclipse-jpa-metamodel.png" alt="eclipse-jpa-metamodel" width="834" height="713" /></a></p>
<p>これで、エンティティクラスに変更が入る度にメタモデルクラスが自動生成されます。メタモデルクラスの名前はエンティティクラスの名前の後ろに _ を付けたものになります。</p>
<p><a href="https://cloudear.jp/blog/wp-content/uploads/2016/02/entity-metamodel.png"><img class="alignnone size-full wp-image-2113" src="https://cloudear.jp/blog/wp-content/uploads/2016/02/entity-metamodel.png" alt="entity-metamodel" width="268" height="81" /></a></p>
<p>&nbsp;</p>
<h2>準備２・SQLをコンソールに出力する設定</h2>
<p>JPAを使いこなすコツはJavaコードを中心に考えることですが、さすがにSQLが見えないと辛すぎます。せめてコンソールにSQLを出力するようにしておきましょう。JPAの設定ファイルであるpersistence.xmlにプロパティを追記します。</p>
<h3>EclipseLinkの場合</h3>
<pre class="lang:xhtml decode:true">&lt;property name="eclipselink.logging.level.sql" value="FINE" /&gt;
&lt;property name="eclipselink.logging.parameters" value="true" /&gt;
&lt;property name="eclipselink.logging.logger" value="org.eclipse.persistence.logging.DefaultSessionLog"/&gt;</pre>
<h3>OpenJPAの場合</h3>
<pre class="lang:xhtml decode:true">&lt;property name="openjpa.Log" value="DefaultLevel=WARN, Runtime=INFO, Tool=INFO, SQL=TRACE"/&gt;
&lt;property name="openjpa.ConnectionFactoryProperties" value="PrintParameters=true" /&gt;</pre>
<p>APサーバにGlassFishを使っているのであれば、EclipseLinkの方を設定してください。</p>
<h2>スキーマ定義をエンティティクラスで行う</h2>
<p>JPAの良さを引き出すコツは、Javaコードを中心に考えることです。まずはスキーマ定義をエンティティクラスで行うようにしてみましょう。</p>
<p>ただ、実はJPAの仕様にはエンティティクラスからDDLを作る機能は含まれていません。JPAの実装であるEclipseLinkやOpenJPAの機能を使います。通常、persistence.xmlにプロパティを追記します。</p>
<h3>EclipseLinkの場合</h3>
<pre class="lang:xhtml decode:true" title="persistence.xml">&lt;property name="eclipselink.ddl-generation" value="create-tables" /&gt;</pre>
<h3>OpenJPAの場合</h3>
<pre class="lang:default decode:true">&lt;property name="openjpa.jdbc.SynchronizeMappings" value="buildSchema(ForeignKeys=true)" /&gt;</pre>
<p>APサーバにGlassFishを使っているのであれば、EclipseLinkの方を設定してください。</p>
<h2>Criteria APIによる検索</h2>
<p>JPAの検索には、JPQLとCriteria APIの２つのやり方があります。JPQLは文字列でクエリを記述するため、コンパイル時に型チェックが全く働きません。</p>
<p>例えば以下のコードは実行時にClassCastExceptionがスローされてしまいます。</p>
<pre class="lang:java decode:true">private static void selectByJPQL(final EntityManager em) {
    final String q = "select e from Tag e";
    for (final User user : em.createQuery(q, User.class).getResultList()) {
        System.out.println(user);
    }
}
</pre>
<p>よく見ると、クエリ文字列が<code>from Tag</code>となっています。結果のエンティティは<code>User</code>型で受けていますから、型が異なっていおり、<strong>実行時に</strong>ClassCastExceptionがスローされるのです。</p>
<p>しかしCriteria APIを使うと、このようなミスは<strong>コンパイル時に</strong>検出できるようになります。上のJPQLをCriteria APIで描き直してみましょう。</p>
<pre class="lang:java decode:true">private static void selectByCriteria(final EntityManager em) {
    final CriteriaBuilder builder = em.getCriteriaBuilder();
    final CriteriaQuery&lt;Tag&gt; criteria = builder.createQuery(Tag.class);
    criteria.from(User.class);

    final TypedQuery&lt;User&gt; query = em.createQuery(criteria);
    for (final User user : query.getResultList()) {
        System.out.println(user);
    }
}</pre>
<p>eclipseでこのコードを書くと、以下のようにコンパイルエラーとしてミスを教えてくれます。</p>
<p><a href="https://cloudear.jp/blog/wp-content/uploads/2016/02/jpa-criteria-error.png"><img class="alignnone size-full wp-image-2116" src="https://cloudear.jp/blog/wp-content/uploads/2016/02/jpa-criteria-error.png" alt="jpa-criteria-error" width="708" height="104" /></a></p>
<p>&nbsp;</p>
<p>このように、Criteria APIを使うと<span style="font-size: 12pt;"><strong>クエリのミスをコンパイル時にチェックできる</strong></span>ようになります。これがCriteria APIの最大の利点です。</p>
<p>また、副次的な効果ですが<strong>変なクエリが書かれない</strong>ようになります。実際の開発現場では、変態的なSQLが横行してチューンングの足枷になったり、特定のDB製品でしか実行できない書き方がされていたりと、SQL周りの問題が起きやすいです。しかしCriteria APIを使えばクエリの記述方法がある程度統一されるため、問題が起きにくく、またレビューしやすくなります。</p>
<h2>Criteria APIによるクエリの基本形</h2>
<p>Criteria APIはJPQLの構造をJavaクラスで表現したものと考えることができます。JPQLの構成要素の基本は次の３つです。</p>
<ol>
<li>from句：どのエンティティ（≒テーブル）からデータを取得するか</li>
<li>where句：抽出条件</li>
<li>select句：どのエンティティ、あるいはプロパティなどを取得するか</li>
</ol>
<p>この３つを踏まえると、Criteria APIを使ったプログラムの基本形は次のようになります。</p>
<pre class="lang:java decode:true">private static void selectUsersByName(final EntityManager em, final String pUserName) {
    // クエリを組み立てるためのオブジェクトを得る
    final CriteriaBuilder builder = em.getCriteriaBuilder();

    // クエリ全体を表現するオブジェクトを作成.
    // 引数として、クエリ結果の型を指定する.
    final CriteriaQuery&lt;User&gt; query = builder.createQuery(User.class);

    // from句指定
    final Root&lt;User&gt; root = query.from(User.class);

    // where句指定
    query.where( //
            builder.equal(root.get(User_.name), pUserName) //
            , builder.isNotNull(root.get(User_.name)) //
    );

    // select句指定.
    // ここではプロパティではなくエンティティそのものを指定.
    // ただしfromと同じエンティティを指定する場合はこの行は省略可能.
    query.select(root);

    // クエリ実行
    final List&lt;User&gt; result = em.createQuery(query).getResultList();
    for (final User user : result) {
        System.out.println(user);
    }
}
</pre>
<p>結果の型を指定できるのがとても強力です。例えば全件数を得るクエリは次のように書けます。</p>
<pre class="lang:java decode:true ">private static void countAllUsers(final EntityManager em) {
    final CriteriaBuilder builder = em.getCriteriaBuilder();

    // 件数なので結果は数値で得るようにする
    final CriteriaQuery&lt;Long&gt; query = builder.createQuery(Long.class);
    final Root&lt;User&gt; root = query.from(User.class);

    // count関数を使う
    query.select(builder.count(root));

    final long count = em.createQuery(query).getSingleResult().longValue();
    System.out.println(count);
}</pre>
<hr />
<p>基本編はここまでです。次回の応用編では、Criteria APIの実戦的な機能をご紹介します。</p>
]]></content:encoded>
			<wfw:commentRss>https://cloudear.jp/blog/?feed=rss2&#038;p=2101</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>AWSで簡単にリレーショナルデータベース (RDS編)</title>
		<link>https://cloudear.jp/blog/?p=1980</link>
		<comments>https://cloudear.jp/blog/?p=1980#comments</comments>
		<pubDate>Tue, 01 Dec 2015 04:57:04 +0000</pubDate>
		<dc:creator><![CDATA[hayato]]></dc:creator>
				<category><![CDATA[AWS]]></category>
		<category><![CDATA[サーバー]]></category>
		<category><![CDATA[データベース]]></category>

		<guid isPermaLink="false">https://cloudear.jp/blog/?p=1980</guid>
		<description><![CDATA[みなさんこんにちは。クラウドで簡単にリレーショナルデータベースを設定しようということでAWSのRDSというサービスを利用してサクサクっとデータベースを構築して行きましょう。 マネジメントコンソールよりRDSを選択 &#038;nb [&#8230;]]]></description>
				<content:encoded><![CDATA[<p>みなさんこんにちは。クラウドで簡単にリレーショナルデータベースを設定しようということでAWSのRDSというサービスを利用してサクサクっとデータベースを構築して行きましょう。</p>
<p><span id="more-1980"></span></p>
<p><strong>マネジメントコンソールよりRDSを選択</strong></p>
<p>&nbsp;</p>
<p><a href="https://cloudear.jp/blog/wp-content/uploads/2015/11/c35e090509e9415cc9a952196d84336e.png"><img class="alignnone size-full wp-image-1983" src="https://cloudear.jp/blog/wp-content/uploads/2015/11/c35e090509e9415cc9a952196d84336e.png" alt="マネジメントコンソールRDS" width="1224" height="539" /></a></p>
<p>RDSをクリック。</p>
<p><a href="https://cloudear.jp/blog/wp-content/uploads/2015/11/663c9ff0157b41e1e730e1724ceea334.png"><img class="alignnone size-full wp-image-1985" src="https://cloudear.jp/blog/wp-content/uploads/2015/11/663c9ff0157b41e1e730e1724ceea334.png" alt="RDSスタート" width="1255" height="484" /></a></p>
<p>&nbsp;</p>
<p>今すぐ始めるをクリック</p>
<p><strong>DBの選択をする</strong></p>
<p><a href="https://cloudear.jp/blog/wp-content/uploads/2015/11/aff540014decd1e76ee34d7c4880c60d.png"><img class="alignnone size-full wp-image-1986" src="https://cloudear.jp/blog/wp-content/uploads/2015/11/aff540014decd1e76ee34d7c4880c60d.png" alt="DB選択" width="1231" height="486" /></a></p>
<p>&nbsp;</p>
<p>データベースを選択する。</p>
<p>※今回はpostgreSQLを選択</p>
<p><a href="https://cloudear.jp/blog/wp-content/uploads/2015/11/acbcd9b2f7ba01a0ed6001fb71a42424.png"><img class="alignnone size-full wp-image-1987" src="https://cloudear.jp/blog/wp-content/uploads/2015/11/acbcd9b2f7ba01a0ed6001fb71a42424.png" alt="RDSインスタンス" width="1254" height="484" /></a></p>
<p>立ち上げるRDSインスタンスを本番用で立ち上げるかを問われます。</p>
<p>今回は無料枠を使用したいので&#8221;いいえ&#8221;にチェックをつけて&#8221;次のステップ&#8221;をクリック。</p>
<p><strong>RDSの詳細設定</strong></p>
<p><a href="https://cloudear.jp/blog/wp-content/uploads/2015/11/ced3702695da488c4d69b8a6c15b3263.png"><img class="alignnone size-full wp-image-1988" src="https://cloudear.jp/blog/wp-content/uploads/2015/11/ced3702695da488c4d69b8a6c15b3263.png" alt="RDS詳細1" width="1236" height="461" /></a></p>
<p>&nbsp;</p>
<p><a href="https://cloudear.jp/blog/wp-content/uploads/2015/11/69c4f7e3bf044e9fa57756fb0c407810.png"><img class="alignnone size-full wp-image-1989" src="https://cloudear.jp/blog/wp-content/uploads/2015/11/69c4f7e3bf044e9fa57756fb0c407810.png" alt="RDS詳細2" width="1230" height="279" /></a></p>
<p>各種設定を行います。</p>
<p>※DBインスタンスのクラスはテスト用なので一番小さいプランにしてます。</p>
<p><a href="https://cloudear.jp/blog/wp-content/uploads/2015/11/367eb073991bb73d691e0827adccb12d.png"><img class="alignnone size-full wp-image-1990" src="https://cloudear.jp/blog/wp-content/uploads/2015/11/367eb073991bb73d691e0827adccb12d.png" alt="RDS詳細設定1" width="1227" height="443" /></a></p>
<p><a href="https://cloudear.jp/blog/wp-content/uploads/2015/11/4e26bee9edcad4d80c238fb1ae0575f1.png"><img class="alignnone size-full wp-image-1991" src="https://cloudear.jp/blog/wp-content/uploads/2015/11/4e26bee9edcad4d80c238fb1ae0575f1.png" alt="RDS詳細設定2" width="1228" height="326" /></a></p>
<p><a href="https://cloudear.jp/blog/wp-content/uploads/2015/11/350372e59d19ba584a8215f6a1298cb3.png"><img class="alignnone size-full wp-image-1992" src="https://cloudear.jp/blog/wp-content/uploads/2015/11/350372e59d19ba584a8215f6a1298cb3.png" alt="RDS詳細設定3" width="1225" height="344" /></a></p>
<p>VPCセキュリティグループをデフォルトを選択。</p>
<p>DBの名前を決めます。</p>
<p>バックアップの保存期間などは後からでも変更可能です。</p>
<p>DBインスタンスの作成をクリックしてインスタンスを立ち上げましょう。</p>
<p><a href="https://cloudear.jp/blog/wp-content/uploads/2015/11/fc7f7f828c0c153ef197c8f3471c0d77.png"><img class="alignnone size-full wp-image-1993" src="https://cloudear.jp/blog/wp-content/uploads/2015/11/fc7f7f828c0c153ef197c8f3471c0d77.png" alt="RDS作成中1" width="1229" height="439" /></a></p>
<p><a href="https://cloudear.jp/blog/wp-content/uploads/2015/11/798a26bc55ab57e248f3c42837c8c77d.png"><img class="alignnone size-full wp-image-1994" src="https://cloudear.jp/blog/wp-content/uploads/2015/11/798a26bc55ab57e248f3c42837c8c77d.png" alt="RDS作成中2" width="1220" height="130" /></a></p>
<p>DBインスタンスを作成中となります。</p>
<p>DBインスタンスの表示をクリックしてみましょう。</p>
<p><a href="https://cloudear.jp/blog/wp-content/uploads/2015/11/72a341ede6d198355e85bb89c084bdd3.png"><img class="alignnone size-full wp-image-1995" src="https://cloudear.jp/blog/wp-content/uploads/2015/11/72a341ede6d198355e85bb89c084bdd3.png" alt="DBダッシュボード" width="1239" height="443" /></a></p>
<p>ステータスが作成中となっていますね？</p>
<p>5分ほど待っていると、、、</p>
<p><a href="https://cloudear.jp/blog/wp-content/uploads/2015/11/a06fe7e1172ea224449ec2989c37be271.png"><img class="alignnone size-full wp-image-1999" src="https://cloudear.jp/blog/wp-content/uploads/2015/11/a06fe7e1172ea224449ec2989c37be271.png" alt="DBダッシュボード2" width="1239" height="476" /></a></p>
<p>ステータスが&#8221;利用可能&#8221;になりました。</p>
<p>これでもうpostgreSQLが使えるようになりました。</p>
<p>せっかくなので作ったdbに接続してみます。</p>
<p><strong>pgAdminでDB(RDS)に接続</strong></p>
<p><span class="emphasis"><em>pgAdmin</em></span> は<a title="pgAdmin インストール" href="http://www.pgadmin.org/">http://www.pgadmin.org/</a>からインストールできます。</p>
<p>pgAdminを起動したらファイル→サーバーの追加を選択。</p>
<p><a href="https://cloudear.jp/blog/wp-content/uploads/2015/11/pgAdmin2.png"><img class="alignnone size-full wp-image-2000" src="https://cloudear.jp/blog/wp-content/uploads/2015/11/pgAdmin2.png" alt="pgAdmin2" width="592" height="535" /></a></p>
<p>RDSのダッシュボードにてDB インスタンスのエンドポイントが記載されています。</p>
<p>それをpgAdminのダイアログのホストへ入力します。</p>
<p>※コロンとポート番号は含めない</p>
<p>先ほど決めたユーザー名、パスワード、port番号を入力します。</p>
<p>OKを選択。</p>
<p><a href="https://cloudear.jp/blog/wp-content/uploads/2015/11/6c82d8a5ca75a8f014bd2a59cb7d36cf.png"><img class="alignnone size-medium wp-image-2001" src="https://cloudear.jp/blog/wp-content/uploads/2015/11/6c82d8a5ca75a8f014bd2a59cb7d36cf.png" alt="スクリーンショット 2015-11-24 14.50.32" width="300" height="83" /></a></p>
<p>&nbsp;</p>
<p>接続されるとDBが追加されます。</p>
<p>&nbsp;</p>
<p>※server dosen&#8217;t listenとエラーになる場合はRDSのセキュリティグループで5432のポートを開放しましょう。</p>
]]></content:encoded>
			<wfw:commentRss>https://cloudear.jp/blog/?feed=rss2&#038;p=1980</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>デッドロックを回避するために</title>
		<link>https://cloudear.jp/blog/?p=1335</link>
		<comments>https://cloudear.jp/blog/?p=1335#comments</comments>
		<pubDate>Sun, 12 Jul 2015 11:42:05 +0000</pubDate>
		<dc:creator><![CDATA[masa]]></dc:creator>
				<category><![CDATA[MySQL]]></category>
		<category><![CDATA[インフラ]]></category>
		<category><![CDATA[データベース]]></category>
		<category><![CDATA[プログラム]]></category>

		<guid isPermaLink="false">https://cloudear.jp/blog/?p=1335</guid>
		<description><![CDATA[みなさんこんにちは masa です。今日はデータベースにおいて致命的なバグであるデッドロックについて取り上げます。プログラマーや DBA な方以外にも聞いたことがあるワードなのではないでしょうか。 開発の流れにおいて、き [&#8230;]]]></description>
				<content:encoded><![CDATA[<p>みなさんこんにちは masa です。今日はデータベースにおいて致命的なバグであるデッドロックについて取り上げます。プログラマーや DBA な方以外にも聞いたことがあるワードなのではないでしょうか。</p>
<p><span id="more-1335"></span></p>
<p>開発の流れにおいて、きちんとトランザクション設計、リソースアクセス順序の設計がされていればデッドロックは理論上は発生しないはずなのですが、オープンソースのソフトウェア基盤なんかを使用している場合、世界中のエンジニアがバラで開発してる宿命というもあり、普通にデッドロックしたりしますｗ</p>
<p>デッドロックは同じタイミングでリソースを確保しにいった際に発生するものなので、リリースするまで発覚しなかったというケースもあります。</p>
<p>&nbsp;</p>
<p><span class="hcss1" style="font-size: 14pt;"><strong>　そもそもデッドロックとは何なのかおさらい</strong></span></p>
<p>まずは問題ないアクセスについて図を描いてみましたのでみてみてください。トランザクション＝スレッドと捉えてもらっても構いません。</p>
<p><a href="https://cloudear.jp/blog/wp-content/uploads/2015/07/deadlock1.png"><img class="alignnone size-full wp-image-1337" src="https://cloudear.jp/blog/wp-content/uploads/2015/07/deadlock1.png" alt="deadlock1" width="600" height="400" /></a></p>
<p>（解説）上の図では各処理が同じ順番でテーブルへアクセスするため、仮に同タイミングで書き込みをしようとしてもどちらか遅れたほうが、相手の処理が終わる（＝ロック解放）のを待つだけです。</p>
<p>&nbsp;</p>
<p>では次は問題のある処理の図です。</p>
<p><a href="https://cloudear.jp/blog/wp-content/uploads/2015/07/deadlock2.png"><img class="alignnone size-full wp-image-1344" src="https://cloudear.jp/blog/wp-content/uploads/2015/07/deadlock2.png" alt="deadlock2" width="600" height="400" /></a></p>
<p>&nbsp;</p>
<p>（解説）上の図では各処理がテーブルへアクセスする順番が逆になっています。この場合にロックと次の処理が <strong>&#8220;たすき掛け&#8221; </strong>の状態になりますので、これ以上処理は進まず停止してしまいます。問題ない処理と決定的に違うのは、<strong>待ち時間が発生するのではなく、永久にストップするという点です。</strong></p>
<p>&nbsp;</p>
<p><strong><span class="hcss1" style="font-size: 14pt;">　どうすればデッドロックを無くせるのか？</span></strong></p>
<p>これは実は非常に難しい質問だと思います。デッドロックはバグそのものですので、ソフトウェアの規模が大きくなれば大きくなるほど潜在的に増えていきます。小さいシステムならまだしも、数百万ステップに及ぶプログラムにおいて、人間ですから設計図がまちがっているかもしれませんし、プログラマーがうっかり実装を手誤ってしまうかもしれません。</p>
<p>個人的にはデッドロックはゼロに近づける（＝減らす）努力はできても、完全にゼロにすることはほぼ不可能であるという立場にいます。ソフトウェアにおいてバグをゼロにすることは不可能であるという考えそのものですが、少しでもデッドロックが起きないように以下のことに気を付ける必要があります。</p>
<ol>
<li><span style="font-size: 12pt; color: #f55858;"><strong>トランザクションからアクセスするテーブルの順番を一貫する</strong></span></li>
<li><span style="font-size: 12pt; color: #f55858;"><strong>不必要にトランザクションを長くしない</strong></span></li>
<li><span style="font-size: 12pt; color: #f55858;"><strong>不必要に FOR UPDATE でロックを掛けない</strong></span></li>
<li><span style="font-size: 12pt; color: #f55858;"><strong>可能な限り行ロックする</strong></span></li>
</ol>
<p>以上のことに気を付けて設計、実装が出来れば限りなくデッドロックを排除できると考えます。</p>
<p>&nbsp;</p>
<p><span class="hcss1" style="font-size: 14pt;"><strong>　それでもデッドロックが起きたときはどうすればいいのか</strong></span></p>
<p>これは実装でカバーしましょう。トランザクションの処理にタイムアウトもしくはリトライ回数を準備しておき、どちらかの処理がロックを解放するようにします。</p>
<p>&nbsp;</p>
<p>いかがでしたか？今日は発見が遅れがちなバグであるデッドロックについて取り上げました。あえて名前は挙げませんが世界的に有名なソフトウェアでもデッドロックは起きています。「デッドロック起こすのは初心者！」などとおごらずに慎重にプロジェクトを進めるよう常に意識したいものです。</p>
]]></content:encoded>
			<wfw:commentRss>https://cloudear.jp/blog/?feed=rss2&#038;p=1335</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
	</channel>
</rss>
