前言
关于Java中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) 执行之后不提交事务。
对于Select没有影响, 但对于Insert和Update的话, 没有提交数据就不会被修改
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()的时候会释放锁,但还是如果应用服务器使用了数据库连接池,连接不会被断开。