JDBC学習の三


事務
四大特性(ACID):   原子性:事務処理を構成する語句が論理ユニットを形成しています。その一部だけを実行することはできません。   整合性(consistentcy):事務処理前後では、データは一致している(データベースのデータ完全性制約)。   隔離性(isolcation):他の事務に対する事務の影響;   持続性(durability):事務処理の効果は永久に保存されます。   connection.set AutoCommt(false)//事務を開始する   connection.co mmit()///事務を提出する   connection.rollback()//ロールバック事務   業務の一部をキャンセルしたい場合のみ、SavePointを使用できます。     SavePoint sp=connection.set SavePoint()//保存ポイントの設定   connection.rollback; //保存点にスクロール   connection.co mmit()
//  &    
static void test() throws SQLException {
		Connection conn = null;
		Statement st = null;
		ResultSet rs = null;
		try {
			conn = JdbcUtils.getConnection();
			conn.setAutoCommit(false);
			conn.setTransactionIsolation(Connection.TRANSACTION_READ_COMMITTED);
			
			st = conn.createStatement();
			String sql = "update user set money=money-10 where id=1";
			st.executeUpdate(sql);

			sql = "select money from user where id=2";
			rs = st.executeQuery(sql);
			float money = 0.0f;
			if (rs.next()) {
				money = rs.getFloat("money");
			}
			if (money > 400)
				throw new RuntimeException("       !");
			sql = "update user set money=money+10 where id=2";
			st.executeUpdate(sql);
			conn.commit();
		} catch (SQLException e) {
			if (conn != null)
				conn.rollback();
			throw e;
		} finally {
			JdbcUtils.free(rs, st, conn);
		}
	}
SavePoint事務保存ポイントの設定
static void test() throws SQLException {
		Connection conn = null;
		Statement st = null;
		ResultSet rs = null;
		Savepoint sp = null;
		try {
			conn = JdbcUtils.getConnection();
			conn.setAutoCommit(false);			
			st = conn.createStatement();
			String sql = "update user set money=money-10 where id=1";
			st.executeUpdate(sql);
			sp = conn.setSavepoint();

			sql = "update user set money=money-10 where id=3";
			st.executeUpdate(sql);

			sql = "select money from user where id=2";
			rs = st.executeQuery(sql);
			float money = 0.0f;
			if (rs.next()) {
				money = rs.getFloat("money");
			}
			if (money > 300)
				throw new RuntimeException("       !");

			sql = "update user set money=money+10 where id=2";
			st.executeUpdate(sql);

			conn.commit();
		} catch (RuntimeException e) {
			if (conn != null && sp != null) {
				conn.rollback(sp);
				conn.commit();
			}
			throw e;
		} catch (SQLException e) {
			if (conn != null)
				conn.rollback();
			throw e;
		} finally {
			JdbcUtils.free(rs, st, conn);
		}
	}
JTA:weblogic、websphere類の容器を使う必要があります。
複数のデータソースにまたがる事務は、JTA容器を使って行う。二つの段階に分けて提出する。
javax.transactions.UserTransation tx=(UserTransation)ctx.lookup("jndi Name");
tx.begin()
//connection 1 connection 2…
tx.com mmit()
//tx.rollback()
分離レベルマルチスレッドを同時読み込みした場合の正確性
汚い読み:一つの事務はもう一つの提出していない並列事務によって書かれたデータを読みました。繰り返して読んではいけません。一つの事務は前にすでに読み取ったデータを読みました。もう一つの提出済みの事務によってデータが修正されました。幻読み:一つの事務は再びデータを読み取り、もう一つの提出済みのデータを読み取ることができます。。
隔離レベル
繰り返して読んではいけません
幻読み
未読(Read uncomitted)



読んで提出しました。
×


繰り返して読むことができます。
×
×

シリアル化可能(Serializable)
×
×
×
  mysqlはデータベースの隔離レベルを調べます。
  select@@txuisolation;
  mysqlデータベース分離レベルを設定します。
  set transaction isolation level read uncomitted;
  mysqlオープン事務:
  startトランスアクション
conn.setTransactionIsolation(Connection.TRANSACTION_READ_COMMITTED);
普通の状況では、データベースの隔離レベルを変更しません。
保存プロセス
難点はどう書きますか?
DELIMITER $$
DROP PROCEDURE EXISTS 'jdbc' . 'addUsers' $$
CREATE PROCEDURE 'jdbc' . 'addUsers' (in pname varchar(45), in birthday date, in 

money float, out pid int)

BEGIN
	insert into user(name,birthday,money) values(pname,birthday,money);
	select last_insert_id() into pid;
END$$
DELIMITER ;
static void ps() throws SQLException {
		Connection conn = null;
		CallableStatement cs = null;
		ResultSet rs = null;
		try {
			// 2.    
			conn = JdbcUtils.getConnection();
			// conn = JdbcUtilsSing.getInstance().getConnection();
			// 3.    

			String sql = "{ call addUser(?,?,?,?) } ";
			cs = conn.prepareCall(sql);
			cs.registerOutParameter(4, Types.INTEGER);
			cs.setString(1, "ps name");
			cs.setDate(2, new java.sql.Date(System.currentTimeMillis()));
			cs.setFloat(3, 100f);

			cs.executeUpdate();

			int id = cs.getInt(4);

			System.out.println("id=" + id);
		} finally {
			JdbcUtils.free(rs, cs, conn);
		}
	}
以上のプログラムは、記憶プロセスによって挿入記録の主キーを取得し、次のAPIを紹介してメインキーを取得する。
メインキーを取得:  PreparedSttement ps=connection.prepareSttement(sql、Sttement.RETURNUGENERATEDUKEYS);  ps.executeUpdate()  ResultSet rs=ps.getGeneranted Key()  int id=rs.getInt(1);
	static int create() throws SQLException {
		Connection conn = null;
		PreparedStatement ps = null;
		ResultSet rs = null;
		try {
			// 2.    
			conn = JdbcUtils.getConnection();
			// conn = JdbcUtilsSing.getInstance().getConnection();
			// 3.    
			String sql = "insert into user(name,birthday, money) values ('name2 gk', '1987-01-01', 400) ";
			ps = conn.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS);
			ps.executeUpdate();

			rs = ps.getGeneratedKeys();//     ResultSet           
			int id = 0;
			if (rs.next())
				id = rs.getInt(1);
			return id;
		} finally {
			JdbcUtils.free(rs, ps, conn);
		}
	}
バッチ処理は、大幅に添削速度を上げることができます。
  PreparedSttement.addBatch()
  PreparedSttement.executeBatch()
直接ロットを使って処理する可能性はあまりありません。
static void createBatch() throws SQLException {
		Connection conn = null;
		PreparedStatement ps = null;
		ResultSet rs = null;
		try {
			conn = JdbcUtils.getConnection();
			String sql = "insert into user(name,birthday, money) values (?, ?, ?) ";
			ps = conn.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS);
			for (int i = 0; i < 100; i++) {
				ps.setString(1, "batch name" + i);
				ps.setDate(2, new Date(System.currentTimeMillis()));
				ps.setFloat(3, 100f + i);

				ps.addBatch();
			}
			int[] is = ps.executeBatch();
		} finally {
			JdbcUtils.free(rs, ps, conn);
		}
	}
スクロール可能な結果セット
    Sttement st=connection.creat Statiment(ResultSet.TYPE.TYPE OLLUSENSITIVE)    Result Set.C.OCUR_UPDDATABLE;
    ResultSet rs=st.executeQuery(sql)
    rs.before First();rs.afterLast();s.first();rs.isfirst();rs.last();rs.isLast();
    rs.absolute(9);rs.moveToInsertRow();
更新可能な結果セット
    conn.createment(Result Set.TYPE);
    rs.udateString(「col name」、「new value」);
    RS.udateRow()
データベースの記録を自動更新した後、新しいデータを読み込む機能は一般的に少ないです。検索と修正を混ぜて操作すると、モジュール化に不利です。
DatabaseMetaDataとParameter MetaData
DatabaseMeta Data=connection.get MetaData()は、DatabaseMetaを通じてデータベースに関する情報を得ることができます。例えば、データベースバージョン、データベース名、データベースメーカー情報、サポート事務、サポートレベル、スクロール結果セットなどです。
java.sql.Connection conn = JdbcUtils.getConnection();
DatabaseMetaData dbmd = conn.getMetaData();
System.out.println("db name: " + dbmd.getDatabaseProductName());
System.out.println("tx: " + dbmd.supportsTransactions());
conn.close();
Parameeter Meta Data pmd=    preparedSttement.getParameterMetaData();パラメータ情報はParameter MetaDataによって得られる。
public class ParameterMetaTest {

	public static void main(String[] args) throws SQLException {
		Object[] params = new Object[] { "lisi", 100f };
		read("select * from user where name=? and  money > ?", params);
	}

	static void read(String sql, Object[] params) throws SQLException {
		Connection conn = null;
		PreparedStatement ps = null;
		ResultSet rs = null;
		try {
			conn = JdbcUtils.getConnection();
			ps = conn.prepareStatement(sql);
//			ParameterMetaData pmd = ps.getParameterMetaData();
//			int count = pmd.getParameterCount();
			for (int i = 1; i <= params.length; i++) {
				// System.out.print(pmd.getParameterClassName(i) + "\t");
				// System.out.print(pmd.getParameterType(i) + "\t");
				// System.out.println(pmd.getParameterTypeName(i));
				ps.setObject(i, params[i - 1]);
			}

			rs = ps.executeQuery();

			while (rs.next()) {
				System.out.println(rs.getInt("id") + "\t"
						+ rs.getString("name") + "\t" + rs.getDate("birthday")
						+ "\t" + rs.getFloat("money"));
			}

		} finally {
			JdbcUtils.free(rs, ps, conn);
		}
	}

}
Result Set MetaData
end