手动提交事务——创建int型ID生成器

线程同步:
    一、synchronized关键字   
    二、数据库的悲观锁
    select * from t_table_id where table_name='t_client' for update;     //查询时把该信息锁住,适合任何数据库
    commit;                                                                                                      //解除上面的信息的锁   


利用数据库的悲观锁创建int类型ID生成器:


    1、DbUtil.java里:
    public static void beginTransaction(Connection conn) {
        try {
            if (conn != null) {
                if (conn.getAutoCommit()) {
                    conn.setAutoCommit(false); //手动提交
                }
            }
        }catch(SQLException e) {}
    }
    
    public static void commitTransaction(Connection conn) {
        try {
            if (conn != null) {
                if (!conn.getAutoCommit()) {
                    conn.commit();
                }
            }
        }catch(SQLException e) {}
    }
    
    public static void rollbackTransaction(Connection conn) {
        try {
            if (conn != null) {
                if (!conn.getAutoCommit()) {
                    conn.rollback();
                }
            }
        }catch(SQLException e) {}
    }
    
    public static void resetConnection(Connection conn) {
        try {
            if (conn != null) {
                if (conn.getAutoCommit()) {
                    conn.setAutoCommit(false);
                }else {
                    conn.setAutoCommit(true);
                }
            }
        }catch(SQLException e) {}
    }
    
    2、IdGenegrator.java中
    /**
 * id生成器
 * @author Administrator
 *
 */
public class IdGenerator {

    /**
     * 根据表名生成该表的序列
     * @param tableName
     * @return 返回生成的序列
     */
    //public static synchronized int generate(String tableName) {
    //public synchronized int generate(String tableName) {
        //synchronized(this) {
    public static int generate(String tableName) {
        //使用数据库的悲观锁for update
        String sql = "select value from t_table_id where table_name=? for update";
        Connection conn = null;
        PreparedStatement pstmt = null;
        ResultSet rs = null;
        int value = 0;
        try {
            conn = DbUtil.getConnection();
            //开始事务
            DbUtil.beginTransaction(conn);
            pstmt = conn.prepareStatement(sql);
            pstmt.setString(1, tableName);
            rs = pstmt.executeQuery();
            if (!rs.next()) {
                throw new RuntimeException();
            }
            value = rs.getInt("value");
            value++; //自加
            modifyValueField(conn, tableName, value);
            //提交事务
            DbUtil.commitTransaction(conn);
        }catch(Exception e) {
            e.printStackTrace();
            //回滚事务
            DbUtil.rollbackTransaction(conn);
            throw new RuntimeException();
        }finally {
            DbUtil.close(rs);
            DbUtil.close(pstmt);
            DbUtil.resetConnection(conn); //重置Connection的状态
            DbUtil.close(conn);
        }
        return value;
    }
    
    /**
     * 根据表名更新序列字段的值
     * @param conn
     * @param tableName
     * @param value
     */
    private static void modifyValueField(Connection conn, String tableName, int value)
    throws SQLException {
        String sql = "update t_table_id set value=? where table_name=?";
        PreparedStatement pstmt = null;
        try {
            pstmt = conn.prepareStatement(sql);
            pstmt.setInt(1, value);
            pstmt.setString(2, tableName);
            pstmt.executeUpdate();
        }finally {
            DbUtil.close(pstmt);
        }
    }
    
    public static void main(String[] args) {
        int retValue = IdGenerator.generate("t_client");
        System.out.println(retValue);
    }
}

你可能感兴趣的:(sql,exception,数据库,String,table,null)