事务特点:ACID
- 原子性(Atomicity):事务管理的系列操作必须全部完成,否则就算失败(类似操作系统的PV原语、信号量)
- 一致性(Consistency):同一个事务只要起始条件一致最终执行的结果一致
- 隔离性(Isolation):多个事务执行时彼此独立,互不干扰
- 持久性(Durability):事务完成提交,如果发生系统故障,其数据也不会丢失
工具类:
public static Connection getConnection(){
try {
Class.forName("com.mysql.jdbc.Driver");
ct = DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/test","squirrel","xiaoyang");
} catch (Exception e) {
e.printStackTrace();
}
return ct;
}
public static void closeConnection(){
try {
if(rs!=null){
rs.close();
}if(ps!=null){
ps.close();
}if(ct!=null){
ct.close();
}
} catch (SQLException e) {
e.printStackTrace();
}
}
事务测试方法:
public static void transactionExperience(){
ct=getConnection();
try {
//禁止sql语句作为单个事务自动提交,这里是将所有的sql语句放在一个事务组统一管理
ct.setAutoCommit(false);
//uid设置为主键自动增长策略,使用插入相同的主键制造异常来测试事务
String sql01="insert into user values(7,'CCCC','CCCC',10,'M')";
String sql02="update user set name='lisi' where name='zhangsan'";
ps=ct.prepareStatement(sql02);
ps.execute();
ps=ct.prepareStatement(sql01);
ps.execute();
ct.commit(); //事务提交
} catch (SQLException e) {
e.printStackTrace();
try {
//如果事务组某个作业未完成则整个事务组管理的作业都不显示实际效果
ct.rollback();
} catch (SQLException e1) {
e1.printStackTrace();
}
}finally{
closeConnection();
}
}
测试前数据库记录:
第一次执行数据库记录:
结论:数据成功更新,新纪录插入
第二次执行测试: 前期准备工作,还原上一次更新的内容,确保看到数据的数据变化 还原的数据库记录:
再次执行之后的数据库记录:
控制台异常日志:
com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException: Duplicate entry '7' for key 'PRIMARY'
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
at java.lang.reflect.Constructor.newInstance(Constructor.java:423)
at com.mysql.jdbc.Util.handleNewInstance(Util.java:395)
at com.mysql.jdbc.Util.getInstance(Util.java:370)
at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:1025)
at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:4187)
at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:4119)
at com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:2570)
at com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java:2731)
at com.mysql.jdbc.ConnectionImpl.execSQL(ConnectionImpl.java:2799)
at com.mysql.jdbc.PreparedStatement.executeInternal(PreparedStatement.java:2139)
at com.mysql.jdbc.PreparedStatement.execute(PreparedStatement.java:1363)
at com.zhiwei.database.TransactionTest.transactionExperience(TransactionTest.java:45)
at com.zhiwei.database.TransactionTest.main(TransactionTest.java:28)
结论:
再次执行测试时数据数据未发生改变,表明update语句尽管成功执行, 但是因为insert语句执行失败,导致整个事务都没有正确执行,这就证明了事务的原子性