- - PR -
テーブル更新処理を全件終えた後にコミットしたい
投稿者 | 投稿内容 | ||||
---|---|---|---|---|---|
|
投稿日時: 2005-04-22 16:02
HibernateやS2はほとんど分からないので、もう確認済みでしたらご容赦下さい。
データベースにmysqlを利用しているようですが、これはトランザクション制御をできるように設定されていますか?たしか、InnoDBとかそんな名称だったと思いますが。 フレームワークなどを使わずに単純なアプリケーションでデータベースの更新、ロールバックは行えるのでしょうか? | ||||
|
投稿日時: 2005-04-22 17:36
taiping様
ご指導ありがとうございます。 MySQLのテーブルタイプはInnoDBで作成しています。 コマンドラインにおけるトランザクション操作ですが、 set autocommit=0 としてcommit、rollbackの確認はしています。 フレームワークを使うことによって、こういうところで悩むとは思ってもいませんでした。 こんな処理、フレームワークなしのJavaアプリやCなら簡単にできるのに・・・。 すっかり路頭に迷ってしまいました。 明示的なトランザクション管理のが「楽」と自分が言っているのは、 きっと今だけのことなんでしょうけど・・・。 ところで現在、log4jでDEBUGレベルのログを出力させていますが、 「トランザクションを開始しました」とか「トランザクションをコミットしました」とか、そのようなメッセージが出てきません。 普通出てくるものなのでしょうか・・・? もし必要なソースがあれば載せますので、ご指導よろしく願い致します。 | ||||
|
投稿日時: 2005-04-22 18:03
私も最近、Seasar2とS2Hibernateを試していますが、特にこういう事象はないですね・・・。
#トランザクションはSeasar2にまかせきりです。 ともあれ、最初からだいぶソース等も変わっているみたいですし、整理の意味も含めてもう一度、関連ファイルをここに提示されてはいかがでしょうか? | ||||
|
投稿日時: 2005-04-22 18:13
>>Odakazu様
ありがとうございます。 もう一度、関連ソースを載せますので、 どうぞよろしくお願いします。 | ||||
|
投稿日時: 2005-04-22 19:47
再びたまこです。(200行以上の長い書き込みになります。)
最新のソースを載せます。 ・s2xwork.xml ・j2ee.dicon ・dicontainer.xml ・s2Hibernate.dicon ・HogeAction.java ・HogeDAO.java ・DAOUtil.java HogeDAOでExceptionを投げ、HogeActionがcatchします。 TransactionはHogeActionで新しいTransactionを開始し、 HogeDAOでは開始されていない場合エラーとします。 Exceptionが発生すると、全体のrollbackになり、 それまでに更新されたUserTblのAgeもrollbackされることを想定してます。 がしかし、現在はExceptionが発生されても、データの更新がされてしまいます。 先ほども書きましたが、log4jのDEBUGレベルのログで、 トランザクション関連のログが出てきません。 (トランザクションを開始します、トランザクションをコミットします、など。) それが何か関係ありそうだと目を付けているところです。 申し訳ありませんが、何かお気づきの点がありましたら、ご教授・アドバイスをお願い致します。 (なお、xmlのヘッダや各種Exceptionなどは割愛させて頂きます。) === s2xwork.xml ==================================== <components> <include path="j2ee.dicon"/> <include path="dicontainer.xml"/> <include path="s2Hibernate.dicon"/> <component class="org.seasar.hibernate.impl.S2SessionFactoryImpl"/> <component name="sessionFactory" class="org.seasar.hibernate.impl.S2SessionFactoryImpl"/> <component name="traceInterceptor" class="org.seasar.framework.aop.interceptors.TraceInterceptor"/> <component name="hogedao" autoBinding="none" class="hoge.dao.HogeDAO"> <aspect pointcut="updUser">j2ee.mandatoryTx</aspect> <aspect>traceInterceptor</aspect> <property name="sessionFactory">sessionFactory</property> </component> <component instance="prototype" autoBinding="none" class="hoge.HogeAction"> <aspect pointcut="execute">j2ee.requiresNewTx</aspect> <property name="hogeDAO">hogedao</property> </component> </components> ==================================================== === j2ee.dicon ===================================== <components namespace="j2ee"> <component name="transactionManager" class="org.seasar.extension.jta.TransactionManagerImpl"/> <component name="requiredTx" class="org.seasar.extension.tx.RequiredInterceptor"/> <component name="requiresNewTx" class="org.seasar.extension.tx.RequiresNewInterceptor"/> <component name="mandatoryTx" class="org.seasar.extension.tx.MandatoryInterceptor"/> <component class="org.seasar.extension.jdbc.impl.BasicResultSetFactory"/> <component class="org.seasar.extension.jdbc.impl.BasicStatementFactory"/> <component name="xaDataSource" class="org.seasar.extension.dbcp.impl.XADataSourceImpl"> <property name="driverClassName">"org.gjt.mm.mysql.Driver"</property> <property name="URL">"jdbc:mysql://localhost/hoge"</property> <property name="user">"hoge"</property> <property name="password">"****"</property> </component> <component name="connectionPool" class="org.seasar.extension.dbcp.impl.ConnectionPoolImpl"> <property name="timeout">600</property> <property name="maxPoolSize">64</property> <destroyMethod name="close"/> </component> <component name="dataSource" class="org.seasar.extension.dbcp.impl.DataSourceImpl"/> </components> ===================================================== === dicontainer.xml ================================= <components namespace="dicontainer"> <component name="s2container" class="org.seasar.framework.container.S2Container" > <arg>container</arg> </component> </components> ===================================================== === s2Hibernate.dicon =============================== <components namespace="s2hibernate"> <include path="j2ee.dicon"/> <component class="org.seasar.hibernate.impl.S2SessionFactoryImpl"/> <component class="org.seasar.hibernate.dao.impl.HibernateDaoMetaDataFactoryImpl"/> <component name="interceptor" class="org.seasar.hibernate.dao.interceptors.S2HibernateDaoInterceptor"/> </components> ===================================================== 以下はJavaソースです。 (Exceptionは種類が多いので割愛させて頂きます。) ・画面から遷移するアクションがHogeAction.java ・HogeAction.javaのexecuteメソッドから呼び出されるDAOがHogeDAO.java ・コンテナの操作やdiconファイルの読み取りはDAOUtilで行います。 === HogeAction.java ================================= package hoge.action; import java.io.File; import com.opensymphony.xwork.Action; import com.opensymphony.xwork.ActionSupport; import org.apache.log4j.Logger; import hoge.dao.HogeDAO; public class HogeAction extends ActionSupport implements Action{ private static final Logger log = Logger.getLogger(HogeAction.class); private String[][] warr; private int lineCnt = 3; // セッターゲッターは割愛 public HogeAction(){ } public String execute(){ warr = new String[lineCnt][10]; if (warr != null){ HogeDAO hogedao = new HogeDAO(); boolean ret; try { // 更新処理 ret = hogedao.updUser(warr,lineCnt); } catch (〜〜Exception 〜〜e){ log.error(〜〜e.getCause()); log.info("異常終了"); return INPUT; } } log.info("正常終了"); return SUCCESS; } } ===================================================== === HogeDAO.java ================================= package hoge.dao; import org.seasar.hibernate.S2SessionFactory; import org.seasar.hibernate.S2Session; import java.util.List; import net.sf.hibernate.Hibernate; import hoge.dao.DAOUtil; import hoge.entity.UserTbl; public class HogeDAO{ /** コンストラクタ **/ public HogeDAO() {} /** 使用するS2SessionFactory */ public S2SessionFactory factory; public void setSessionFactory(S2SessionFactory factory) { this.factory = factory; } public boolean updUser(String[][] warr,int lineCnt) throws 〜〜Exception{ int i,j; UserTbl im = new UserTbl(); DAOUtil du = new DAOUtil(); du.setUp(); HogeDAO hogedao = du.getDAO(); factory = (S2SessionFactory) du.getSessionFactory(); S2Session session = factory.getSession(); // 配列の箱分繰り返し for (j = 0 ; j < lineCnt-1 ; j++){ for (i = 0 ; i < 10 ; i++){ if (j == lineCnt-2 && warr[j][i]== null){ session.flush(); return true; } // 該当データが存在するか検索 List result = session.find("from UserTbl as u where u.userId = ?",warr[j][i],Hibernate.STRING); if (result.size() > 0) { usertbl = (UserTbl) result.get(0); } else { throw new Exception("エラーメッセージ"); } // 現在の年齢に1足した数で更新します int userAge = usertbl.getAge() + 1; usertbl.setAge(userAge); session.update(usertbl); i++; } j++; } session.flush(); return true; } } ===================================================== === DAOUtil.java ================================= package hoge.dao; import org.seasar.framework.container.S2Container; import org.seasar.framework.container.factory.S2ContainerFactory; public class DAOUtil{ private String diconPath = "s2xwork.xml"; protected S2Container container; protected void setDiconPath(String diconPath){ this.diconPath = diconPath; } public void setUp(){ container = S2ContainerFactory.create(diconPath); } public HogeDAO getDAO(){ return (HogeDAO)container.getComponent(HogeDAO.class); } public Object getSessionFactory(){ return container.getComponent("sessionFactory"); } protected Object getComponent(Class type){ return container.getComponent(type); } protected Object getComponent(String name){ return container.getComponent(name); } ===================================================== | ||||
|
投稿日時: 2005-04-22 22:35
私も、2日ほど前からいじり始めたばかりで、トランザクションもDAOで使っているだけなので、推測というかあてずっぽうに近いのですが・・・
HogeActionにおいて、
ここで例外を握りつぶしているように見えますが、これだとコミットされてしまわないでしょうか? HogeActionでトランザクションを開始しているように見えるので、ここで例外を握りつぶすと、そういう挙動になるのかなぁと思いまして・・・。 [ メッセージ編集済み 編集者: Odakaz 編集日時 2005-04-22 22:48 ] | ||||
|
投稿日時: 2005-04-22 23:17
あと、スレッドの最初の方でAnthyhimeさんが仰っていたように、ここまでのトランザクション処理は要らないかもしれませんね。
DAOの中だけで完結しそうに思えます。 | ||||
|
投稿日時: 2005-04-23 23:15
Odakazさま
何度もご教授ありがとうございます。 > あと、スレッドの最初の方でAnthyhimeさんが仰っていたように、ここまでのトランザクション処理は要らないかもしれませんね。 確かにトランザクションが必要なのは、DAO部分のみですね。 そうなると、HogeActionのaspect pointcutをなくし、HogeDAOのメソッドのaspect pointcutをrequiresNewTxにすることで、そのメソッド内のみのトランザクション制御が行えるかと思い、実行してみました。 しかし、やはりテーブルデータはcommitされてしまい、うまくいきません。。 Odakazさんはlog4jを使っていらっしゃいますか? DEBUGログにトランザクションの開始・コミット・ロールバックなどのログは出ますか? 私のログにはそれが出てきません。 何が違うのでしょう。。 トランザクションに関するログは、以下の1行しか出ません。 2005-04-23 22:37:38,466 INFO net.sf.hibernate.transaction.TransactionManagerLookupFactory - No TransactionManagerLookup configured (in JTA environment, use of process level read-write cache is not recommended) [http-8080-Processor24] (TransactionManagerLookupFactory.java:33) hibernate.cfg.xmlには、 <class-cache usage="read-write" class="hoge.entity.UserTbl" /> と記述しています。 すみません、何か手がかりがありましたら、教えてください。。 |