java积累——数据库手动控制事务工具类

来源:互联网 发布:蒋勤勤的长相知乎 编辑:程序博客网 时间:2024/05/16 10:50


   引言


   在项目中对数据库操作的时候保证事务的完整性是非常重要的,尤其是一个功能中需要对数据库多次操作的时


更是需要小心,其实简单的说:只要保证多次操作使用一个Connection就可以使他们在一个事务中,但是数据库


jdbc默认在执行完executeQuery、executeUpdate等方法以后会自动提交事务,这样我们多次操作的时候就不能保证


事务的完整性,所以需要我们手动控制事务的提交和回滚操作,下面提供一个帮助类。

    

package com.bjpowernode.drp.util;import java.sql.Connection;import java.sql.DriverManager;import java.sql.PreparedStatement;import java.sql.ResultSet;import java.sql.SQLException;import java.sql.Statement;/** *  * @author zhenghao * */public class DbUtil {public static Connection getConnection(){/*Connection conn=null;try {Class.forName("oracle.jdbc.driver.OracleDriver");String url="jdbc:oracle:thin:@127.0.0.1:1521:databaseName";String username="userName";String password="password";try {conn=DriverManager.getConnection(url, username, password);} catch (SQLException e) {// TODO Auto-generated catch blocke.printStackTrace();}} catch (ClassNotFoundException e) {// TODO Auto-generated catch blocke.printStackTrace();}return conn;*/Connection conn=null;try {JdbcConfig jdbcConfig=XmlConfigReader.getInstance().getJdbcConfig();Class.forName(jdbcConfig.getDriverName());try {conn=DriverManager.getConnection(jdbcConfig.getUrl(), jdbcConfig.getUserName(), jdbcConfig.getPassword());} catch (SQLException e) {// TODO Auto-generated catch blocke.printStackTrace();}} catch (ClassNotFoundException e) {// TODO Auto-generated catch blocke.printStackTrace();}return conn;}public static void close(Connection conn){if (conn!=null) {try {conn.close();} catch (SQLException e) {e.printStackTrace();}}}public static void close(Statement statement){if (statement!=null) {try {statement.close();} catch (SQLException e) {e.printStackTrace();}}}public static void close(ResultSet rs) {if(rs!=null){try {rs.close();} catch (SQLException e) {e.printStackTrace();}}}public static void beginTransaction(Connection conn){if (conn!=null) {try {if(conn.getAutoCommit()){conn.setAutoCommit(false);}} catch (SQLException e) {// TODO Auto-generated catch blocke.printStackTrace();}}}public static void commitTransaction(Connection conn){try {if(conn!=null){if (!conn.getAutoCommit()) {conn.commit();}}} catch (Exception e) {// TODO: handle exception}}public static void rollbackTransaction (Connection conn) {try {if(conn!=null){if (!conn.getAutoCommit()) {conn.rollback();}}} catch (Exception e) {// TODO: handle exception}}public static void resetTransaction(Connection conn){try {if(conn!=null){if (conn.getAutoCommit()) {conn.setAutoCommit(false);}else{conn.setAutoCommit(true);}}} catch (Exception e) {// TODO: handle exception}}}

   上面的工具类中提供了数据库的连接操作;手动开启事务、提交事务、事务回滚、恢复事务状态;关闭


Connection ;关闭Statement;关闭ResultSet等等操作,这样在和数据库打交道的时候会方便很多。 


   手动控制事务示例演示


  当我们添加一个节点以后,需要判断这个节点是不是叶子(是有有子节点)而改变is_leaf这个字段的值;


public void addClientOrRegion(Client clientOrRegion) {StringBuffer sbSql = new StringBuffer();sbSql.append("insert into t_client ( ").append("id, pid, client_level_id, ").append("name, client_id, bank_acct_no, ").append("contact_tel, address, zip_code, ").append("is_leaf, is_client) ").append("values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) ");Connection conn = null;PreparedStatement pstmt = null;try {conn = DbUtil.getConnection();pstmt = conn.prepareStatement(sbSql.toString());<strong><span style="color:#ff0000;">DbUtil.beginTransaction(conn);</span></strong>// 根据表明获得id,利用id生成器pstmt.setInt(1, IdGenerator.generate("t_client"));pstmt.setInt(2, clientOrRegion.getPid());pstmt.setString(3, clientOrRegion.getClientLevel().getId());pstmt.setString(4, clientOrRegion.getName());pstmt.setString(5, clientOrRegion.getClientId());pstmt.setString(6, clientOrRegion.getBankAcctNo());pstmt.setString(7, clientOrRegion.getContactTel());pstmt.setString(8, clientOrRegion.getAddress());pstmt.setString(9, clientOrRegion.getZipCode());pstmt.setString(10, clientOrRegion.getIsLeaf());pstmt.setString(11, clientOrRegion.getIsClient());pstmt.executeQuery();// 根据id查询分销商或者区域,确定是否为叶子Client client = findClientOrRegionById(clientOrRegion.getPid());if (Constants.YES.equals(client.getIsLeaf())) {// 如果非叶子 应该改为叶子modifyIsLeafField(conn, clientOrRegion.getPid(), Constants.NO);}<strong><span style="color:#ff0000;">DbUtil.commitTransaction(conn);</span></strong>} catch (Exception e) {// TODO: handle exceptione.printStackTrace();<strong><span style="color:#ff0000;">DbUtil.rollbackTransaction(conn);</span></strong>} finally {DbUtil.close(pstmt);<strong><span style="color:#ff0000;">DbUtil.resetTransaction(conn);</span></strong>DbUtil.close(conn);}}

当我们得到connection以后,调用方法来设置事务的提交为手动提交,这样当我们将两步操作都完成以后自


己手动提交,如果遇到错误以后调用方法回滚事务,这样我们就可以事务的完整性。在最后释放资源的时候不要忘记


恢复事务的提交状态。


   小结


   事务在数据库中是非常重要的,尤其是项目比较大的时候,如果不能保证事务会给我们带来很大的麻烦有时候


甚至是灾难。

1 0