我们在mysql的时候介绍了什么是事务安全问题,当然,到了JAVA程序了,这个问题也值得我们去关注
JDBC事务
我们还是来看一段代码:
import java.sql.Connection;
import java.sql.Statement;
import com.yht.utils.JdbcUtil;
public class Transfer {
public static void main(String[] args) {
Connection conn = null;
Statement st = null;
try{
conn = JdbcUtil.getConnection();
st = conn.createStatement();
String sql1 = "update account set money = money+500 where id=1";
String sql2 = "update account set money = money-500 where id=2";
int result1 = st.executeUpdate(sql1);
int result2 = st.executeUpdate(sql2);
if(result1==1&&result2==1){
System.out.println("转账成功");
}else{
System.out.println("转账失败");
}
}catch (Exception e){
e.printStackTrace();
}finally {
JdbcUtil.closeAll(st, conn, null);
}
}
}
执行前 : 执行后:
运行很顺利,但是如果在两句executeUpdate语句之间出现异常:
正常报异常,但是结果:
出现了转账错误。。。。。
错误原因是因为每一条sql语句都是一个单独的事务,JDBC中默认一个事务执行结束自动提交。所以在异常没出现之前上一句的转账已经执行了。。
所以我们给设置成非自动提交:
意料之中:
结果并没有发生改变。因为我们没有进行提交。那我们提交一次:
结果:
成功!!!,而且这里注意一点,这里的缓存文件是JAVA的缓存文件,比如上一次提交的时候结果会存入缓存文件中,如果是在mysql数据库中这里再运行一次会进行两次改变,但是因为缓存文件时JAVA的,程序一运行完就释放了,所以如果没有commit,那么缓存的信息就释放了。这次操作就完全报废了。
还有一个回滚操作,在讲mysql事物安全的时候说是配合其他程序执行的。所以这里真的就可以显示它的用处了:
我们再次在两句执行语句之间加上制造异常语句。然后执行:
这次:数据库中的数据将不会再发生改变
事务的四大特性:ACID
感受完上面代码,相信已经对事务有了一些认识,那么下面介绍一下事务我们一定要维护的四大特性:
事务特性 | 含义 |
原子性 (Atomicity) | 事务是一个不可分割的工作单位,事务中的操作要么都发生,要么都不发生。 |
一致性 (Consistency) | 事务前后数据的完整性必须保持一致 |
隔离性 (Isolation) | 是指多个用户并发访问数据库时,一个用户的事务不能被其它用户的事务所干扰,多个 并发事务之间数据要相互隔离,不能相互影响。 |
持久性 (Durability) | 指一个事务一旦被提交(commit),它对数据库中数据的改变就是永久性的,接下来即使数据库发 生故障也不应该对其有任何影响 |