JDBC中的事务提交机制
JDbC 事务机制:
JDBC中的事务是自动提交的,即JDBC中DML语句执行一次,事务自动提交一次,
这是JDBC默认的事务行为,但是在实际的业务开发中,通常都是N条DML语句共同联合才能完成的,
必须保证这些DML语句在同一个事务中同时成功或者同时失败
import java.sql.Connection;import java.sql.DriverManager;import java.sql.PreparedStatement;import java.sql.SQLException;/*** JDbC 事务机制:* 1、JDBC中的事务是自动提交的,即JDBC中DML语句执行一次,事务自动提交一次* 这是JDBC默认的事务行为,但是在实际的业务开发中,通常都是N条DML语句共同联合才能完成的* 必须保证这些DML语句在同一个事务中同时成功或者同时失败* 2、以下程序会先验证JDBC的事务是否是自动提交机制*测试结果:JDBC中只要执行任意一条SQL语句,事务就自动提交一次**/public class Demo05 {public static void main(String[] args) {Connection conn = null;PreparedStatement ps =null;try {//1.注册驱动Class.forName("com.mysql.jdbc.Driver");//2.获取连接// conn = DriverManager.getConnection("jdbc:mysql//localhost:3306/bjpowernode","root","333");注意URL的书写格式conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/bjpowernode","root","333");conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/bjpowernode","root","333");//3.获取数据库预编译对象,写SQL语句String sql ="update dept set dname = ? where deptno = ?";//4.执行第一个SQL语句ps =conn.prepareStatement(sql);ps.setString(1,"X部门");ps.setInt(2,30);int count = ps.executeUpdate();System.out.println(count);//第二次执行SQL语句ps.setString(1,"Y部门");ps.setInt(2,60);count = ps.executeUpdate();System.out.println(count);//5.遍历查询结果集} catch (Exception e) {e.printStackTrace();}finally {if (ps !=null){try {ps.close();} catch (SQLException e) {e.printStackTrace();}}}if(conn !=null){try {conn.close();} catch (SQLException e) {e.printStackTrace();}}}}
JDBC 完成银行转账业务
import java.sql.Connection;import java.sql.DriverManager;import java.sql.PreparedStatement;import java.sql.SQLException;/***sql脚本* drop table if exists t_cat;* create table t_act(* actno int,* balance double(7,2)//注意7表示有效数字的个数,2表示小数位的个数。* );* insert into t_act(actno,balance) values (111,20000);* insert into t_act(actno,balance) values (222,0);* commit;* selece *from t_act;*** */public class Demo06 {public static void main(String[] args) {Connection conn = null;PreparedStatement ps =null;try {//1.注册驱动Class.forName("com.mysql.jdbc.Driver");//2.获取连接conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/bjpowernode","root","333");//将自动提交机制修改为手动提交机制conn.setAutoCommit(false);//开启事务//3.获取数据库预编译对象,写SQL语句//4.执行SQL语句String sql ="update t_act set balance = ? where actno = ?";ps = conn.prepareStatement(sql);//传值ps.setDouble(1,10000);ps.setInt(2,111);int count = ps.executeUpdate();/**手动生成异常String s = null;s.toString();*///第二次传值ps.setDouble(1,10000);ps.setInt(2,222);count +=ps.executeUpdate();System.out.println(count == 2 ? "转账成功":"转账失败");//执行到此说明程序没出现异常,此时可以提交事务conn.commit();//手动提交事务//5.遍历查询结果集} catch (Exception e) {//回滚事务if (conn !=null ){try {conn.rollback();} catch (SQLException ex) {e.printStackTrace();}}}finally {if (ps !=null){try {ps.close();} catch (SQLException e) {e.printStackTrace();}}}if(conn !=null){try {conn.close();} catch (SQLException e) {e.printStackTrace();}}}}
JDBC 的工具类
package utils;/** JDBC 工具类* */import java.sql.*;public class DBUtil {/** 工具类中的构造方法都是私有的。* 因为工具类中的方法都是静态的,不需要new对象,直接采用类名调用* */private DBUtil(){}static {try {Class.forName("com.mysql.jdbc.Driver");} catch (ClassNotFoundException e) {e.printStackTrace();}}/*** 获取数据库连接对象* @return连接对象* @throws SQLException*/public static Connection getConnection() throws SQLException{return DriverManager.getConnection("jdbc:mysql://localhost:3306/bjpowernode","root","333");}/*** 关闭资源* @param conn 数据库连接对象* @param ps 数据库操作对象* @param rs 结果集*/public static void close(Connection conn, Statement ps, ResultSet rs){if (rs!= null){try {rs.close();} catch (SQLException e) {e.printStackTrace();}}if (ps!= null){try {ps.close();} catch (SQLException e) {e.printStackTrace();}}if (conn!= null){try {conn.close();} catch (SQLException e) {e.printStackTrace();}}}}
JDBC 完成模糊查询
package DemoCode;/**两个任务:* 第一、测试util工具类是否可用* 第二、JDBC进行模糊查询** */import utils.DBUtil;import java.sql.Connection;import java.sql.PreparedStatement;import java.sql.ResultSet;import java.sql.SQLException;public class Demo07 {public static void main(String[] args) {Connection conn =null;PreparedStatement ps = null;ResultSet rs = null;try {conn = DBUtil.getConnection();//获取预编译的数据库操作对象//错误的写法// String sql = "select ename from emp where ename like '_?%'";// ps = conn.prepareStatement(sql);// ps.setString(1,"A");String sql = "select ename from emp where ename like ?";ps = conn.prepareStatement(sql);ps.setString(1,"_A%");rs = ps.executeQuery();while (rs.next()){System.out.println(rs.getString("ename"));}} catch (Exception e) {e.printStackTrace();}finally {DBUtil.close(conn,ps,rs);}}}
乐观锁与悲观锁简介
行级锁:select enamel,job,sal from emp where job='manager' for update;
其中加入的‘for update’称为行级锁,即其他语句在该事务结束之前无法对岗位为‘manager’这一行记录进行改动。又被称为悲观锁
悲观锁:事务必须排队执行。数据锁住了,不允许并发。
乐观锁:支持并发,事务也不需要排队,但是需要一个版本号。
package DemoCode;/*Demo08、09进行演示乐观锁与悲观锁这个程序开启一个事务,这个事务专门进行查询,并且使用行级锁/悲观锁,锁住相关的记录* */import utils.DBUtil;import java.sql.Connection;import java.sql.PreparedStatement;import java.sql.ResultSet;import java.sql.SQLException;public class Demo08 {public static void main(String[] args) {Connection conn = null;PreparedStatement ps =null;ResultSet rs = null;try {conn = DBUtil.getConnection();//开启事务conn.setAutoCommit(false);String sql = "select ename,job,sal from emp where job = ? for update";ps = conn.prepareStatement(sql);ps.setString(1,"MANAGER");rs = ps.executeQuery();while (rs.next()){System.out.println(rs.getString("ename")+","+rs.getString("job")+","+rs.getInt("sal"));}//提交事务(事务结束)conn.commit();} catch (SQLException e) {if (conn != null){try {conn.rollback();//回滚事务(事务结束)} catch (SQLException ex) {e.printStackTrace();}}}finally {DBUtil.close(conn,ps,rs);}}}
package DemoCode;/*Demo08、09进行演示乐观锁与悲观锁这个程序开启一个事务,这个事务进行修改锁定的记录* */import utils.DBUtil;import java.awt.dnd.DnDConstants;import java.sql.Connection;import java.sql.PreparedStatement;import java.sql.SQLException;public class Demo09 {public static void main(String[] args) {Connection conn = null;PreparedStatement ps =null;try {conn = DBUtil.getConnection();conn.setAutoCommit(false);String sql = "update emp set sal =sal*1.1 where job = ?";ps = conn.prepareStatement(sql);ps.setString(1,"MANAGER");int count = ps.executeUpdate();System.out.println(count);conn.commit();} catch (SQLException e) {if (conn !=null){try {conn.rollback();} catch (SQLException ex) {e.printStackTrace();}}}finally {DBUtil.close(conn,ps,null);}}}
JDBC到此可告一段落!