(1)这个程序执行任意一条DML语句,则自动提交一次。违背事务机制:同时发生,同时失败
package com.jdbc;
import java.sql.*;
/**
*JDBC事务机制:
* 1.JDBC中的事务是自动提交的,什么是自动提交?
* --只要执行任意一条DML语句,则自动提交一次,这是JDBC默认的事务行为。
* --但是在实际的业务逻辑中,通常都是N条DML语句共同联合才能完成,必须保证他们这些DML语句在同一个事务中
* 同时成功或者同时失败。
* 2.以下程序先来验证一下JDBC的事务是否是自动提交机制。
* ---要执行任意一条DML语句,则自动提交一次
* */
public class JDBCTest09 {
public static void main(String[] args) {
Connection conn = null;
PreparedStatement ps = null;
try {
//1.注册驱动
Class.forName("com.mysql.cj.jdbc.Driver");
//2.获取连接
conn=DriverManager.getConnection("jdbc:mysql://localhost:3306/bjpowernode?serverTimezone=GMT%2B8","root","jh7851192");
//3.获取预编译数据库操作对象
String sql="update dept set dname = ? where deptno = ?";
//第一次给占位符?传值
ps=conn.prepareStatement(sql);
ps.setString(1,"x部门");
ps.setInt(2,70);
//4.执行SQL语句
int count=ps.executeUpdate();
System.out.println(count==1?"成功":"失败");
//重新给占位符传值
ps.setString(1,"y部门");
ps.setInt(2,112);
ps=conn.prepareStatement(sql);
//4.执行SQL语句
int count02=ps.executeUpdate();
System.out.println(count02==1?"成功":"失败");
} 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();
}
}
}
}
}
(2)为了解决上述自动提交- - -> 事务的重要三行代码(手动):
conn.setAutoCommit(false); //手动开启事务
conn.commit(); //手动提交事务
conn.rollback(); //手动回滚事务
package com.jdbc;
/**
* 事务机制:要同时成功或者同时失败。
* --将自动提交改为手动提交
* --重点三行代码?
* conn.setAutoCommit(false); //手动开启事务
* conn.commit(); //手动提交事务
* conn.rollback(); //手动回滚事务
* */
import java.sql.*;
/**
* sql脚本:
* drop table if exists t_act;
* create table t_act(
* actno bignit,
* balance double(7,2) 注意: 7表示有效数字的个数,2表示小数位的个数
* );
* insert into t_act(actno,balance) values (111,20000);
* insert into t_act(actno,balance) values (222,0);
* select * from t_act;
* */
public class JDBCTest10 {
public static void main(String[] args) {
Connection conn =null;
PreparedStatement ps= null;
try {
//1.注册驱动
Class.forName("com.mysql.cj.jdbc.Driver");
//2.获取连接
conn= DriverManager.getConnection("jdbc:mysql://localhost:3306/bjpowernode?serverTimezone=GMT%2B8","root","jh7851192");
//将自动提交机制修改为手动提交
conn.setAutoCommit(false); //开启事务
//3.获取预编译数据库操作对象
String sql="update t_act set balance = ? where actno=?";
ps=conn.prepareStatement(sql);
//给?传值
ps.setDouble(1,10000);
ps.setInt(2,111);
//4.执行SQL语句
int count=ps.executeUpdate();//count默认值为1
/*该句是空指针异常,下面语句一定不会执行,因为报异常后就
直接跳到匹配的catch语句块中处理异常了,不再执行异常下面语句。
String s=null;
s.toString();*/
//给?重新传值
ps.setDouble(1,10000);
ps.setInt(2,222);
count+=ps.executeUpdate();
System.out.println(count==2?"转账成功":"转账失败");
//程序能够走到这里说明以上程序没有异常,事务结束,手动提交数据
conn.commit(); //提交事务
} catch (Exception e) {
if(conn != null){
try{
conn.rollback(); // 回滚事务
}catch(SQLException e1){
e1.printStackTrace();
}
}
e.printStackTrace();
}finally {
//6.释放资源
if(ps!=null){
try {
ps.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if(conn!=null){
try {
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}
}
结果:(1)生成t_act表格,表中数据是111账户为20000
(2)事务机制要同时发生,则111向222账户转账10000,各自账户都还有10000.