• ベストアンサー

MySQLでロールバックできない!

JDBCでMySQLに接続し、ロールバック/コミットしたいのですが、以下の例外が発生してロールバックできません。 java.sql.SQLException: General error: Warning: Some non-transactional changed tables couldn't be rolled back 同じコードで、PostgreSQLでは問題なく動作します。 MySQLはDBMSとして自動コミットになっているとのことですが、JDBCからロールバックしたいときはどうすれば良いのでしょうか? 有名な問題なのかもしれませんが、回避策が見つけられませんでした。 ご回答、よろしくお願いします。

noname#4486
noname#4486
  • Java
  • 回答数2
  • ありがとう数3

質問者が選んだベストアンサー

  • ベストアンサー
  • misoka
  • ベストアンサー率35% (56/160)
回答No.2

参考としてURL、日本MySQLユーザ会へのリンクを掲げます。 MySQL J-Docに詳細情報があります。 “6.7 MySQL Transactional and Locking Commands” あたり、もしくは “MySQL はどのように標準互換か?” の章あたりが参考になるかもしれません。 わたしは試してみていないので、何ともいえませんが。 ちなみに、 例外のメッセージは、トランザクションを使わずに変更した テーブルをロールバックすることはできません、というような 意味ですね。 何かこの辺のことは言うまでもない感じもしますが。

参考URL:
http://www.mysql.gr.jp/
noname#4486
質問者

お礼

お礼が遅くなって申し訳ございません。 お二人のご案内に従ってマニュアルを参照してみました。 それによるとどうも、できるくさいのですが、具体的な手順が不明のままです。デフォルトでできないとしているので、使わないのが正解なのかと思っています。 ご回答ありがとうございました。

その他の回答 (1)

  • osamuy
  • ベストアンサー率42% (1231/2878)
回答No.1

こいつでしょうか? 結局、rollbackしなくてすむような、コードにしないといけない、のではないかと。

参考URL:
http://www.mysql.gr.jp/jpdoc/3.23.x/manual.ja_toc.html#Non-transactional_tables

関連するQ&A

  • mySQLでロールバックされずコミットされる

    お世話になっております。 現在JavaのjdbcでmySQLに接続してデータを更新する処理を入れているのですが AutoCommitをfalseにしておりrollbak処理をしているにも関わらず commitがされている状態になっています。 ログ出力にてメソッド内でsetAutoCommitがfalse、 rollbakが実行されていて、commitが実行されいないのは確認済みですが 実際にはデータがロールバックされずcommitされたのちに コネクションが閉じられています。 このような勝手なコミットがされてしまう原因で 他に何か思い当たる確認点はないでしょうか? ご力添えお願いします。

    • ベストアンサー
    • Java
  • iBatisでのロック、コミットとロールバック

    お世話になります。 現在、javaで以下のような処理を考えています。 1.空っぽのLockテーブルをロックする。ロックできた人だけ、以下の処理を行う。  ロックできなかった人は待ち状態。 2.selectとかupdateとかinsertとか、Httpリクエスト投げたりレスポンス受け取ったり。  select,update,insertするテーブルはLockテーブルではない。 3.2の処理が全て成功したら、1でロックしたテーブルをコミットして解除。  どこかで失敗したら全部ロールバック。 これを、以下の環境で実装したいです。 ・Java 1.6.0_16 ・Spring 2.5.1 ・iBatis 2.3.0.677 ・PostgreSQL 8.3.8 iBatisでLockとLockの解除、コミットとロールバックを行う方法が分かりません。 どなたかご存知でしたら、よろしくお願いします。

    • ベストアンサー
    • Java
  • mysqlでCSVインポートでトランザクション管理出来る

    只今、mysqlを使用して開発しております。 行き詰まっておりまして 大変申し訳ありませんが、ご教授の程、よろしくお願いいたします。 要件は以下になります。 ・CSVファイルデータをインポートする。 ・CSVファイルは複数なので、全ての処理が終わった段階でコミット・もしくはロールバックする。 (トランザクション管理が出来ればよいです。) ※LOAD DATA INFILEでトランザクション管理しようとしたのですが LAODのトランザクション管理は5.1系じゃないと出来ないようですので、 出来ませんでした。 mysqlのバージョン :5.0.24

    • ベストアンサー
    • MySQL
  • MySQLでアンダーバーを検索

    JDBCを使ってMySQLにアクセスしようと、以下のようなプログラムを書いたのですが、executeQueryでエラーが出てしまいます。 検索したいデータ(100100_0001)に、アンダーバー(_)が入っているので、それが問題であるような気がします。 説明が分かり難くてすいませんが、どなたか助けていただけますでしょうか。 非常に困っております。。。 エラー内容================================================= java.sql.SQLException: General error message from server: "Illegal mix of collations (latin1_swedish_ci,IMPLICIT) and (sjis_japanese_ci,COERCIBLE) for operation '='" =========================================================== プログラム=========================================================== String a ; String b : String key ; ResultSet rs; a = "100100" ; b = "0001" ; key = a + "_" + b ; //↑これを key = a + "\_" + b ; とすると、「エスケープ文字が不正です」となってコンパイルが通りませんでした sql = "SELECT * from quote_dtl WHERE qd_id = " + "\'" + key + "\'"; rs_dtl = stmt.executeQuery(sql) ; ===========================================================

    • ベストアンサー
    • Java
  • このサイト(教えて!goo) のDBMSは・・・?

      久し振りの質問です。 このサイト(教えて!goo) のバックエンドDBMSは何でしょうか?(笑) アプリケーションがPHPで構築されていることは、ブラウザのアドレスバーを見れば容易に想像できるのですが、使用DBMSをユーザ側で確認する術はないですよね?(ハッキング等の違法行為を除く) データ量、更新頻度が比較的多いこと、24時間常時稼動であることから、Oracleかな・・・?と思うのですが、ご存知の方いらっしゃいましたら、教えてください。 「この規模(機能)はPostgreSQLやMySQLでは不可能(可能)」といった間接的なコメントでも結構です。  

  • トランザクションとlast_insert_id

    トランザクション中にinsertする予定のテーブル(未コミット)のauto_increment値を取得することはできるのでしょうか。 以下のような処理を期待しているのですが、hoge1テーブルのauto_increment値が取得できずに困っております。last_insert_id に関わらず、hoge1テーブルのauto_increment値が取得できる方法があれば教えてください。 (1) トランザクション開始 (2) $sql=" INSERT INTO hoge1(name) value('あああ'); "; (3) ( ロールバック ) (4) $key=mysql_insert_id(); (5) $sql2=" INSERT INTO hoge2(hoge1_primary,age) value($key,'20歳'); "; (6) ( ロールバック ) (7) コミット (8) トランザクション終了 よろしくお願いします。 環境: php5,mysql5 (InnoDB)

    • ベストアンサー
    • MySQL
  • JDBC実行時に認証エラーとなる

    皆さんこんにちわ。 JDBCに関して解決に至らない事があり、 アドバイスをいただきたく、質問させていただきます。 MySQLの初心者ですが、 優しい目でアドバイスいただけると大変ありがたいです。 どこにでもあるような下記JDBCを利用して、 MySQLに接続を行うだけの簡単なプログラムをコンパイルし、 実行してみましたが、 MySQLでの認証に引っかかってしまい、 接続に失敗しています。 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ import java.net.*; import java.sql.*; class test5 { public static void main(String args[]) { try { //JDBCドライバをロードする Class.forName("com.mysql.jdbc.Driver"); //データベースに接続する String url = "jdbc:mysql://localhost/testdb"; String user = "test"; String pass = "test!"; Connection con = DriverManager.getConnection(url,user,pass); System.out.println("データベースに接続しました"); //データベースから切断する con.close(); System.out.println("データベースを切断しました"); } catch (Exception e) { System.out.println("例外 " + e + " が発生しました"); } } } # javac test5.java # java test5 例外 java.sql.SQLException: Invalid authorization specification message from server: "Access denied for user 'root'@'localhost' (using password: YES)" が発生しました 試しに、「test」というユーザ名と「test!」というPWDで、 MySQLにログインし、 「testdb」というDBを選択すると、 それは可能なようです。 また、 「mysql-connector-java-3.0.17-ga-bin.jar」は、 「/usr/java/jdk1.6.0_07/lib/mysql-connector-java-3.0.17-ga」ディレクトリに 保存されています。 環境変数は、 以下のようにしています。 export CLASSPATH=.:$JAVA_HOME/lib/mysql-connector-java-3.0.17-ga/mysql-connector-java-3.0.17-ga-bin.jar ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ # mysql -u test -p Enter password: mysql> use testdb; Reading table information for completion of table and column names You can turn off this feature to get a quicker startup with -A Database changed

    • ベストアンサー
    • MySQL
  • トランザクション処理について

    質問させて下さい。 以下の処理を行なっております。 1. トランザクション処理開始 2. テーブルAからデータをDELETE 3. テーブルBへデータをINSERT 4. トランザクション処理終了 上記処理の場合の「TYPE=InnoDB」指定の仕方が不安です。 現在はロールバックの可能性のあるテーブルAのみ「TYPE=InnoDB」を指定しています。 その状態でコミットもうまくいっているのですが、テーブルBに「TYPE=InnoDB」を 指定しなくてもよいものなのでしょうか。 環境 MySql 4.0.24

    • ベストアンサー
    • MySQL
  • JDBCレルムによるFORMパスワード認証

    JDBCレルムによるFORMパスワード認証 以下のようなエラーが出てデータベースに接続できません: 2010/03/28 4:13:21 org.apache.catalina.realm.JDBCRealm start 致命的: データベース接続オープン中に例外が発生しました java.sql.SQLException: org.gjt.mm.mysql.Driver at org.apache.catalina.realm.JDBCRealm.open(JDBCRealm.java:704) at org.apache.catalina.realm.JDBCRealm.start(JDBCRealm.java:786) server.xmlのデータベースに関する部分は以下の通りです: <Realm className="org.apache.catalina.realm.JDBCRealm" connectionURL="jdbc:mysql://127.0.0.1/authorization" driverName="org.gjt.mm.mysql.Driver" connectionName="root" connectionPassword="" ←ここは空欄でいいですか? roleNameCol="role" userCredCol="password" userNameCol="username" userRoleTable="roles" userTable="users" /> …検索してみるとorg.gjt.mm.mysql.Driverは古いのでcom.mysql.jdbc.Driverを使うべき、とありました (http://www.javadrive.jp/servlet/auth/index5.html)。 しかし、org.gjt.mm.mysql.Driverをcom.mysql.jdbc.Driverに変えてみましたが、結果は変わりません。 本来、どちらが正しいのでしょうか? ←まずはこの質問の回答をお願いします あと、自分のMySQLはユーザー名は"root"で設定してあるのですが、パスワードは設定していません (つまり、MySQLをコマンドラインから起動するときはパスワードを空欄のままEnterを押して入れます)。 自分の場合、connectionNameとconnectionPasswordは上記の通りで良いのでしょうか?  ←次にこの質問の回答をお願いします Tomcatのライブラリは以下の通りです: Directory of C:\apache-tomcat-6.0.26\lib [.] [..] annotations-api.jar catalina-ant.jar catalina-ha.jar catalina-tribes.jar catalina.jar el-api.jar jasper-el.jar jasper-jdt.jar jasper.jar jsp-api.jar servlet-api.jar tomcat-coyote.jar tomcat-dbcp.jar tomcat-i18n-es.jar tomcat-i18n-fr.jar tomcat-i18n-ja.jar MySQLのデータはちゃんと入力されており、MySQL単体であれば、もちろん動作します: mysql> select * from roles; +----+----------+--------+ | id | username | role | +----+----------+--------+ | 1 | nakamura | member | | 2 | tanaka | member | +----+----------+--------+ mysql> select * from users; +----+----------+----------+ | id | username | password | +----+----------+----------+ | 1 | nakamura | 1234 | | 2 | tanaka | 5678 | +----+----------+----------+ …では、宜しくお願いします。

    • ベストアンサー
    • Java
  • SQLServer2005 リンクサーバーのトランザクションについて

    [OSのVER]:Windows Server 2003 SP2 (x64) [SQLServerのVER]:2005 Standard Edition SP3 お世話になります。トーシロです。 以下の現象で解決方法がわからず悩んでいます。 解決方法がございましたご教授頂けますでしょうか。 よろしくお願い致します。 状況: ・インスタンスAとインスタンスBがあります。 ・インスタンスAにリンクサーバーとしてインスタンスBを登録してあります。 ・インスタンスA.テーブルaにJDBC経由でデータをインサートします。 ・インスタンスA.テーブルaインサートトリガーXにて、 インスタンスB.テーブルbにデータをインサートします。 ・トリガーXはT-SQLで記述しています。 ・トリガーX内にBEGIN TRANSACTION、COMMIT TRANSACTIONを記述しています。 (記述しないとBEGINとCOMMITの対応数が違うという内容のエラーとなりました。) ・JDBC経由でのデータのインサートは一連のトランザクション内となります。 JDBC実装内容: 1.setAutoCommit(false) ↓ 2.executeUpdate()で複数回のインサート ↓ 3.commit() ↓ 4.例外発生時はrollback() ・ユーザはインスタンスA、インスタンスB共に「sa」を使用しています。 ・MSDTCは「開始」となっています。 上記状況で以下の操作をします。 1件目をインスタンスA.テーブルaにインサート→正常終了するデータをトリガーXにてインスタンスB.テーブルbにインサートします。 2件目をインスタンスA.テーブルaにインサート→制約違反が起きるデータをトリガーXにてインスタンスB.テーブルbにインサートします。 この際にエラーが発生しますが、インスタンスB.テーブルbの1件目のデータがロールバックされず、コミットされてしまいます。 インスタンスB.テーブルbの1件目のデータがコミットされないようにするには、どのような実装が必要になるのでしょうか。 (同一インスタンス内のテーブルではロールバックされます。) 以下実行時エラーです。 2パターンがランダムに出力されました。 パターン1: Error Code:1206 SQL State:S000118 com.microsoft.sqlserver.jdbc.SQLServerException: Microsoft 分散トランザクション コーディネータ (MS DTC) により、この分散トランザクションがキャンセルされました。 at com.microsoft.sqlserver.jdbc.SQLServerException.makeFromDatabaseError(Unknown Source) at com.microsoft.sqlserver.jdbc.IOBuffer.processPackets(Unknown Source) at com.microsoft.sqlserver.jdbc.SQLServerStatement.sendExecute(Unknown Source) at com.microsoft.sqlserver.jdbc.SQLServerStatement.doExecuteUpdate(Unknown Source) at com.microsoft.sqlserver.jdbc.SQLServerPreparedStatement.executeUpdate(Unknown Source) at TestInsert.write(TestInsert.java:86) at TestInsert.main(TestInsert.java:43) パターン2: Error Code:3971 SQL State:S0001 com.microsoft.sqlserver.jdbc.SQLServerException: サーバーはトランザクションを再開できませんでした。説明: 3400000002。 at com.microsoft.sqlserver.jdbc.SQLServerException.makeFromDatabaseError(Unknown Source) at com.microsoft.sqlserver.jdbc.IOBuffer.processPackets(Unknown Source) at com.microsoft.sqlserver.jdbc.SQLServerConnection.connectionCommand(Unknown Source) at com.microsoft.sqlserver.jdbc.SQLServerConnection.sendRollback(Unknown Source) at com.microsoft.sqlserver.jdbc.SQLServerConnection.rollback(Unknown Source) at TestInsert.write(TestInsert.java:96) at TestInsert.main(TestInsert.java:43) 以上、よろしくお願い致します。

専門家に質問してみよう