[Seasar-user:15030] Re: [S2JDBC] SQL自動生成のメモリ消費

Koichi Kobayashi [E-MAIL ADDRESS DELETED]
2008年 7月 15日 (火) 05:00:17 JST


小林 (koichik) です.

Date:    Tue, 15 Jul 2008 04:00:28 +0900
From:    Koichi Kobayashi <[E-MAIL ADDRESS DELETED]>
To:      [E-MAIL ADDRESS DELETED]
Subject: [Seasar-user:15029] Re: [S2JDBC] SQL自動生成のメモリ消費

> 試しに,PreparedStatement のキャッシュを無効にして試して
> みてください.

またまたごめんなさい.m(__)m
PreparedStatement のキャッシュサイズを 0 にすると,
作成された PreparedStatement が速攻でクローズされて
しまい,使おうとした時にはもうクローズ済みでアウトです.

そこを修正しても,現在の S2JDBC だとキャッシュが前提のため,
PreparedStatement をクローズするタイミングがなくなって
しまいます.

対応するにも手間がかかりそうなので,まずは問題を
明確にするということで,Employee2Logic を次のように
修正して試してみてください.

    public DataSource dataSource;

    @RequiresNewTx
    public void exec(final int count) {
        Connection con = dataSource.getConnection();
        PreparedStatement ps = con.prepareStatement(
            "INSERT INTO employee (name, job_type, salary, version) " +
            "VALUES (?, ?, ?, 1)");
        for(int i = 0; i < count; i++) {
            String name = new StringBuilder()
                .append("example_")
                .append(i)
                .toString();
            insert(ps, name);
        }
        ps.close();
        con.close();
    }

    public void insert(final PreparedStatement ps, final String name) {
        ps.setString(1, name);
        ps.setString(2, JobType.ANALYST.name());
        ps.setInt(3, 100);
        ps.executeUpdate();
        ResultSet rs = ps.getGeneratedKeys();
        if (rs.next()) {
            rs.getInt();
        }
        rs.close();
    }

このケースで OutOfMemoryError になり,PreparedStatement の
作成/クローズをループの内側でするように exec() を

    @RequiresNewTx
    public void exec(final int count) {
        Connection con = dataSource.getConnection();
        for(int i = 0; i < count; i++) {
            PreparedStatement ps = con.prepareStatement(
                "INSERT INTO employee (name, job_type, salary, version) "
+
                "VALUES (?, ?, ?, 1)");
            String name = new StringBuilder()
                .append("example_")
                .append(i)
                .toString();
            insert(ps, name);
            ps.close();
        }
        con.close();
    }

と修正して OOME にならないのであれば,Connector/J の
問題というか S2JDBC との相性の問題になりますね.


-- 
<component name="koichik">
    <property name="fullName">"Koichi Kobayashi"</property>
    <property name="email">"[E-MAIL ADDRESS DELETED]"</property>
    <property name="blog">"http://d.hatena.ne.jp/koichik"</property>
</component>



Seasar-user メーリングリストの案内