jdbc 系列文章列表, 请查看目录: 《jdbc学习笔记》
数据库事务, 通俗来将, 就是将多个增删改操作组成一个原子操作来执行, 原子操作要么同时成功, 要么失败. 而且在事务的执行过程中, 子操作涉及到的数据具有线程安全的特性, 不会被并发的其它事务所篡改.
数据库事务有四大特性, 简称ACID:
原子性(Atomicity): 指事务作为一个整体, 事务包含的所有操作要么同时成功, 要么同时失败. 不存在部分成功情况一致性(Consistency): 事务执行必须从一个执行状态变化为另一个一致性状态隔离线(Isolation): 事务的执行不能被其它事务干扰, 即事务执行过程中, 内部设计到的各个数据对其它并发事务来讲是隔离的.持久性(Durability): 事务一旦被提交, 便是永久. 后续数据库故障等不应该对已提交的事务产生影响.虽然说事务不提交和事务回滚, 数据库表中数据均不会产生变化, 但这两者还是有很大的差别的:
开启手动提交事务之后, 所有增删改操作, 都会被暂时存在数据库的"临时区域中", 当执行提交操作时, 才会将"临时区域"中的修改才会生效.当执行回滚操作时, 会将"临时区域"中的修改清空 当发生异常时, 若不进行回滚, 那会带来一下隐患: "临时区域"不会提交, 当其它操作再拿到相同连接时, 执行commit操作时, 会将之前的操作也同时提交数据库是有隔离级别的, 虽然说事务未提交,也可能由于数据库隔离级别的问题, 导致被其它线程所有读取. 因此会导致脏读问题虽然说, 在企业开发过程中, 我们通常无须手工管控事务, 通常都是交由Spring 处理. 但是我们依然需要了解Jdbc 是如何控制事务的, 因为Spring 底层也是通过jdbc 来控制事务的. 有兴趣的话完全可以通过动态代理自己实现一个类似Spring 的声明式事务.
通过控制int a=1/10; 代码来测试事务提交与回滚需要注意的是, 如果事务提交之后,再抛异常, 是不生效的. public void test_transcation() { //1. 获取数据库连接 Connection connection = DbConnUtil.getConnection(); Statement statement = null; try { //2. 关闭手工提交事务 connection.setAutoCommit(false); //3. 执行数据库操作 statement = connection.createStatement(); statement.execute("insert into t_user values(1001, 'zhangsan', 'zhangsan123')"); statement.execute("insert into t_user values(1002, 'lisi', 'lisi123')"); // 模拟异常, 需要注意的是, 需要在事务提交前抛出异常. 事务一旦提交, 纵使发生了异常, 也不能进行回滚了. // int a=1/10; //4. 提交事务 connection.commit(); } catch (SQLException e) { // 回滚事务 connection.rollback(); e.printStackTrace(); }finally { // 关闭连接, connection, Statement 等... DbConnUtil.release(statement, connection); } }