JDBC进行事务管理
事务的四个特征:
原子性 : 是指事务中包含的操作都被看做是一个逻辑单元
一致性: 开始前和结束后数据库都处于一致性状态
隔离性: 对数据库修改的多个事务是彼此隔离的
持久性 事务完成之后对系统的影响是永久的
现举一个例子:有两张表,一张是user表,一张是地址表,user表和address表通过user_id关联。现在我要插入一个人的信息,需要向两个表中插入数据,如下:
insert into tbl_user(id,name,password,email) values(10,'xiongda','123','xiongda@qq.com')
insert into tbl_address(id,city,country,user_id) values(1,'hangzhou','china',10)
现在存在一个问题时,第二条语句的id与表中其他数据重复,存在了主键冲突。如果不加上事务管理,那么就只能导致user表插入了数据,但是address表就不能插入数据。
我们把这两个表的插入操作看作是一个事务,这也就破坏了事务的一致性。
所以我们要做到,要么都插入,要么都不插入,也就是满足事务的原子性。
JDBC中实现事务管理的代码如下:
public class TransactionTest { public static Connection getConnection(){ Connection conn=null; try { Class.forName("com.mysql.cj.jdbc.Driver").newInstance(); conn=(Connection)DriverManager.getConnection("jdbc:mysql://localhost:3306/test?useSSL=FALSE&serverTimezone=UTC","root","xb199795"); } catch (InstantiationException | IllegalAccessException | ClassNotFoundException | SQLException e) { // TODO Auto-generated catch block e.printStackTrace(); } return conn; } public static void insertUser(Connection conn) throws SQLException { String sql="insert into tbl_user(id,name,password,email)"+ "values(10,'xiongda','123','xiongda@qq.com')"; Statement st=conn.createStatement(); int count=st.executeUpdate(sql); System.out.println("向用户表插入了"+count+"条记录!"); } public static void insertAddress(Connection conn) throws SQLException { String sql="insert into tbl_address(id,city,country,user_id)"+ "values(1,'hangzhou','china',10)"; Statement st=conn.createStatement(); int count=st.executeUpdate(sql); System.out.println("向地址表插入了"+count+"条记录!"); } public static void main(String[] args) { Connection conn =getConnection(); try { conn.setAutoCommit(false); insertUser(conn); insertAddress(conn); conn.commit(); } catch (SQLException e) { System.out.println("************事务处理出现异常***********"); e.printStackTrace(); try { conn.rollback(); System.out.println("*********事务回滚成功***********"); } catch (Exception e2) { // TODO: handle exception e2.printStackTrace(); }finally { try { conn.close(); } catch (SQLException e1) { // TODO Auto-generated catch block e1.printStackTrace(); } } } } }
user表中也没有新增数据。