Javaトランザクション管理学習用JDBCサンプルコードの詳細説明

黄舟
リリース: 2017-03-27 10:30:32
オリジナル
1327 人が閲覧しました

この記事は主に Java トランザクション管理の学習に関連する情報を紹介しています。この記事は非常に詳細に説明されているので、必要な方はぜひご覧ください。

Java トランザクションとは何ですか?

通常の概念では、トランザクションはデータベースにのみ関連します。

トランザクションは、ISO/IEC によって設定された ACID 原則に準拠する必要があります。 ACID は、原子性、一貫性、分離性、耐久性の略語です。トランザクションのアトミック性とは、トランザクションの実行中に障害が発生すると、トランザクションによって行われた変更が無効になることを意味します。一貫性とは、トランザクションが失敗したときに、トランザクションの影響を受けるすべてのデータをトランザクションが実行される前の状態に復元する必要があることを意味します。分離とは、トランザクションがコミットされるまで、トランザクション実行中のデータへの変更が他のトランザクションから認識されないことを意味します。永続性とは、トランザクションの実行が失敗した場合でも、送信されたデータのステータスが正しい必要があることを意味します。

平たく言えば、データベースの観点から見ると、トランザクションは一連の SQL 命令であり、いずれかの実行でエラーが発生した場合に実行されます。何らかの理由で命令が実行されると、それまでに実行された命令はすべてキャンセルされます。より簡単な答えは、すべての実行が成功するか、キャンセルされて実行されないかのどちらかです。

トランザクションの概念はデータベースから来ているので、Java トランザクションとは何ですか?どういう関係があるのでしょうか?

実際、Java アプリケーション システムがデータベースを操作したい場合、JDBC を通じて実装されます。追加、変更、削除はすべて、対応するメソッドを通じて間接的に実装され、トランザクション制御もそれに応じて Java プログラム コードに渡されます。したがって、データベース操作トランザクションは慣例的に Java トランザクションと呼ばれます。

トランザクションの特徴:

1) アトミック性: トランザクションはデータベースの論理的な作業単位であり、データ変更の場合は、すべてのトランザクションが実行されるか、アトミックな作業単位である必要があります。どれも実行されません。

2) 一貫性: トランザクションが完了すると、すべてのデータが一貫している必要があります。関連するデータベースでは、すべてのデータの整合性を維持するために、トランザクションの変更にすべてのルールを適用する必要があります。

3) 分離: トランザクションの実行は他のトランザクションの影響を受けることができません。

4) 耐久性: トランザクションが送信されると、トランザクションの操作は DB に永続的に保存されます。この時点でロールバック操作を実行しても、変更は元に戻されません。

トランザクション: 同時実行制御の単位であり、ユーザー定義の操作シーケンスです。これらの操作はすべて実行されるか、まったく実行されないかのいずれかであり、これらは統合された作業単位です。 SQL Server はトランザクションを通じて、論理的に関連する一連の操作をバインドして、サーバーがデータの整合性を維持できるようにします。トランザクションは通常、トランザクションの開始で始まり、コミットまたはロールバックで終了します。コミットとは、送信、つまりトランザクションをコミットするすべての操作を意味します。具体的には、トランザクション内のデータに対するすべての更新はディスク上の物理データベースに書き戻され、トランザクションは正常に終了します。ロールバックとは、ロールバックを意味します。つまり、トランザクションの実行中に何らかの障害が発生し、システムはトランザクション内のデータベースに対する完了した操作をすべて取り消し、トランザクションが開始された状態にロールバックします。

トランザクションの自動コミット: 個々のステートメントがトランザクションです。各ステートメントの後には暗黙的なコミットがあります。 (デフォルト)

明示的なトランザクション: トランザクションの開始表示で始まり、コミットまたはロールバックで終了します。

暗黙的トランザクション: 接続が暗黙的 トランザクション モードで動作する場合、SQL サーバー データベース エンジン インスタンスは、現在のトランザクションをコミットまたはロールバックした後、新しいトランザクションを自動的に開始します。物事の始まりを説明する必要はなく、各トランザクションをコミットまたはロールバックするだけです。ただし、各トランザクションはコミットまたはロールバックによって明示的に終了します。接続によって暗黙的トランザクション モードがオンに設定されると、データベース エンジン インスタンスが次のステートメントのいずれかを初めて実行するときに暗黙的トランザクションが自動的に開始されます: alter table、insert、create、open、delete、revoke、drop 、select、fetch、truncate table、grant、update の場合、トランザクションは commit または rollback ステートメントが発行されるまで有効のままです。最初のトランザクションがコミットまたはロールバックされた後、次回接続で上記のステートメントのいずれかが実行されると、データベース エンジン インスタンスは新しいトランザクションを自動的に開始します。このインスタンスは、暗黙的トランザクション モードがオフになるまで、暗黙的トランザクション チェーンを生成し続けます。

JDBCトランザクション管理

JDBCを使用する際のトランザクションを管理する方法。コードを直接見てください

サンプルコード

/** 
 * @Title: JDBCTrans.java 
 * @Package com.oscar999.trans 
 * @Description: 
 * @author XM 
 * @date Feb 14, 2017 4:38:27 PM 
 * @version V1.0 
 */ 
package com.oscar999.trans; 
 
import java.sql.Connection; 
import java.sql.DriverManager; 
import java.sql.SQLException; 
import java.sql.Statement; 
 
/** 
 * @author 
 * 
 */ 
public class JDBCTrans { 
 
 public JDBCTrans() { 
 
 } 
 
 /** 
 * 
 * @param sHostName 
 * @param sPortNumber 
 * @param sSid 
 * @param userName 
 * @param password 
 * @return 
 * @throws SQLException 
 */ 
 public Connection getConnection(String sHostName, String sPortNumber, String sSid, String userName, String password) throws SQLException { 
 Connection conn = null; 
 String url = getOraclURL(sHostName, sPortNumber, sSid); 
 conn = DriverManager.getConnection(url,userName,password); 
 return conn; 
 } 
 
 /** 
 * 
 * @param conn 
 * @param sql 
 * @throws SQLException 
 */ 
 public void add(Connection conn, String sql) throws SQLException { 
 Statement stmt = null; 
 try { 
  stmt = conn.createStatement(); 
  stmt.execute(sql); 
 } catch (SQLException e) { 
  // TODO Auto-generated catch block 
  e.printStackTrace(); 
 } finally { 
  if (stmt != null) 
  stmt.close(); 
 } 
 } 
 
 /** 
 * @param args 
 */ 
 public static void main(String[] args) { 
 // TODO Auto-generated method stub 
 String sHostName = ""; 
 String sPortNumber = ""; 
 String sSid = ""; 
 String userName = ""; 
 String password = ""; 
 
 sHostName = ""; 
 sPortNumber = ""; 
 sSid = ""; 
 userName = ""; 
 password = ""; 
 
 try { 
  Class.forName("oracle.jdbc.driver.OracleDriver"); 
 } catch (ClassNotFoundException e1) { 
  // TODO Auto-generated catch block 
  e1.printStackTrace(); 
 } 
  
 JDBCTrans jdbcTrans = new JDBCTrans(); 
 Connection conn = null; 
 try {  
  conn = jdbcTrans.getConnection(sHostName, sPortNumber, sSid, userName, password); 
  conn.setAutoCommit(false);// can't insert, update 
  
  //1. add SQL 
  String addSQL = "insert into TEST_TABLE values('name1','value1')"; 
  jdbcTrans.add(conn,addSQL); 
  
 } catch (SQLException e) { 
  // TODO Auto-generated catch block 
  e.printStackTrace(); 
 } finally { 
  /*if (conn != null) 
  { 
  try { 
   conn.close(); 
  } catch (SQLException e) { 
   // TODO Auto-generated catch block 
   e.printStackTrace(); 
  } 
  }*/ 
 } 
 
 } 
 
 private String getOraclURL(String sHostName, String sPortNumber, String sSid) { 
 String url = "jdbc:oracle:thin:@" + sHostName + ":" + sPortNumber + ":" + sSid; 
 return url; 
 } 
 
}
ログイン後にコピー

上記のコードの説明は次のとおりです:

上記のコードにはいくつかの説明があります:

1. トランザクションをコミットしないでください。処刑後。 conn.setAutoCommit(false)

選択には影響しませんが、挿入と更新の場合は、送信されなければデータは変更されません


2. conn.close(); 关闭Connection的代码有被Mark掉, 是想呈现conn.setAutoCommit(false)的效果。

原因是在 Connection Close的时候会执行一次Commit.

而如果Connection是在应用服务器中使用连接池的话, Connection就不会被Close, 也就不会执行Commit.

3. setAutoCommit(false) 用法大多数是在要执行多条语句才提交。

所以针对以上第三点, 更接近实际的状况的代码如示例代码2

示例代码2

/** 
 * @Title: JDBCTrans.java 
 * @Package com.oscar999.trans 
 * @Description: 
 * @author XM 
 * @date Feb 14, 2017 4:38:27 PM 
 * @version V1.0 
 */ 
package com.oscar999.trans; 
 
import java.sql.Connection; 
import java.sql.DriverManager; 
import java.sql.SQLException; 
import java.sql.Statement; 
 
/** 
 * @author 
 * 
 */ 
public class JDBCTrans { 
 
 public JDBCTrans() { 
 
 } 
 
 /** 
 * 
 * @param sHostName 
 * @param sPortNumber 
 * @param sSid 
 * @param userName 
 * @param password 
 * @return 
 * @throws SQLException 
 */ 
 public Connection getConnection(String sHostName, String sPortNumber, String sSid, String userName, String password) throws SQLException { 
 Connection conn = null; 
 String url = getOraclURL(sHostName, sPortNumber, sSid); 
 conn = DriverManager.getConnection(url, userName, password); 
 return conn; 
 } 
 
 /** 
 * 
 * @param conn 
 * @param sql 
 * @throws SQLException 
 */ 
 public void add(Connection conn, String sql) throws SQLException { 
 Statement stmt = null; 
 try { 
  stmt = conn.createStatement(); 
  stmt.execute(sql); 
 } catch (SQLException e) { 
  // TODO Auto-generated catch block 
  e.printStackTrace(); 
 } finally { 
  if (stmt != null) 
  stmt.close(); 
 } 
 } 
 
 /** 
 * @param args 
 */ 
 public static void main(String[] args) { 
 // TODO Auto-generated method stub 
 String sHostName = ""; 
 String sPortNumber = ""; 
 String sSid = ""; 
 String userName = ""; 
 String password = ""; 
 
 sHostName = ""; 
 sPortNumber = ""; 
 sSid = ""; 
 userName = ""; 
 password = ""; 
 
 try { 
  Class.forName("oracle.jdbc.driver.OracleDriver"); 
 } catch (ClassNotFoundException e1) { 
  // TODO Auto-generated catch block 
  e1.printStackTrace(); 
 } 
 
 JDBCTrans jdbcTrans = new JDBCTrans(); 
 Connection conn = null; 
 try { 
  conn = jdbcTrans.getConnection(sHostName, sPortNumber, sSid, userName, password); 
  conn.setAutoCommit(false);// can't insert, update 
 
  // 1. add SQL 1 
  String addSQL = "insert into TEST_TABLE values('name1','value1')"; 
  jdbcTrans.add(conn, addSQL); 
 
  //2. add SQL 2 
  addSQL = "insert into TEST_TABLE values('name2','value2')"; 
  jdbcTrans.add(conn, addSQL); 
  
  conn.commit(); 
 } catch (SQLException e) { 
  // TODO Auto-generated catch block 
  if(conn!=null){ 
   try { 
   conn.rollback(); 
   } catch (SQLException e1) { 
   e1.printStackTrace(); 
   } 
  }  
  e.printStackTrace(); 
 } finally { 
  if (conn != null) { 
  try { 
   conn.close(); 
  } catch (SQLException e) { 
   // TODO Auto-generated catch block 
   e.printStackTrace(); 
  } 
  } 
 } 
 
 } 
 
 private String getOraclURL(String sHostName, String sPortNumber, String sSid) { 
 String url = "jdbc:oracle:thin:@" + sHostName + ":" + sPortNumber + ":" + sSid; 
 return url; 
 } 
 
}
ログイン後にコピー

这里需要说明的是: conn.rollback(); 

只要执行有异常,就要rollback , 这一步必不可少

如果没有在执行出现异常的时候进行回滚。如果在执行第一条语句之后出现异常,con既没有提交也没有回滚,表就会被锁住(如果oracle数据库就是行锁),而这个锁却没有机会释放。

可能在执行con.close()的时候会释放锁,但还是如果应用服务器使用了数据库连接池,连接不会被断开。

总结

以上がJavaトランザクション管理学習用JDBCサンプルコードの詳細説明の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

関連ラベル:
ソース:php.cn
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート