JDBC--处理事务
1、事务是指一组逻辑操作单元,使数据从一种状态转换到另一种状态。
2、事务的四个属性:
--1)原子性:事务是一个不可分割的工作单位,事务中的操作要么都发生要么都不发生;
--2)一致性:事务必须是数据库从一个一致性状态变换到另外一个一致性状态
--3)隔离性:事务的执行不能被其他事务干扰,即一个事务内的操作及使用的数据对并发的其他事物是隔离的,并发执行的各个事务之间不能相互干扰;
--4)持久性:事务一旦被提交,他对数据库中数据的改变是永久性的。
3、使用JDBC操作数据库时,为了防止程序出现异常导致有些sql语句被执行而另外一些sql语句未执行,违反一致性,就需要使用事务来操作数据库,一旦发生异常,但是若没有提交(commit),则数据库仍可回滚到异常发生之前的状态;
4、使用事务时必须保证所有操作使用同一个连接(Connection),同时由于JDBC操作数据库时会为每一次操作自动提交(commit),因此要想正常使用事务,在操作之前需要使用Connection的setAutoCommit(false)方法,来关闭自动提交,当操作完之后再使用Connection的commit()方法手动提交;若出现异常,则可以使用其rollback()方法回滚事务。
5、编程实例:
public void testTransaction(){ DAO dao = new DAO(); Connection conn = null; try{ //获取连接 conn = JDBCUtils.getConnection(); //关闭自动提交 conn.setAutoCommit(false); //进行第一次数据操作 String sql1 = "UPDATE accounts SET SALARY = SALARY - 500 WHERE id = 1"; dao.update(conn, sql1); //模拟异常发生 int a = 10 / 0; //进行第二次数据操作 String sql2 = "UPDATE accounts SET SALARY = SALARY + 500 WHERE id = 2"; dao.update(conn, sql2); //提交事务 conn.commit(); }catch(Exception e){ //若出现异常,则回滚事务 try { conn.rollback(); } catch (SQLException e1) { e1.printStackTrace(); } }finally{ if(conn != null){ //关闭数据库连接 try { conn.close(); } catch (SQLException e) { e.printStackTrace(); } } } }
6、数据库的隔离级别:对于同时运行的多个事务,当这些事务访问数据库中相同的数据时,如果没有采取必要的隔离机制,就会导致各种并发问题:
--读脏数据:对于两个事务T1,T2,T1读取了已经被T2更新但没有提交的字段之后,若T2回滚,T1读取的内容就是无效的;
--不可重复读:对于两个事务T1,T2,T1读取了一个字段,然后T2更新了该字段之后,T1再次读取该字段时值与第一次读取不同;
--幻读:对于两个事务T1,T2,T1从一个表中读取了一个字段,然后T2在该表中插入了一些新的行之后,如果T1再次读取同一个表,就会读取多出的几行。
7、为了防止出现上面的问题,数据库系统必须具有隔离并发运行各个事务的能力。使它们不会相互影响,避免各种并发问题;
8、一个事务与其他事务隔离的程度称为隔离级别。数据库规定了多种事务隔离级别,不同隔离级别对应不同的干扰程度,隔离级别越高,数据一致性就越好,但并发性越弱;
9、四种隔离级别:
--1)READ UNCOMMITTED:读未提交数据
--2)READ COMMITED:读已提交数据
--3)REPEATABLE READ:可重复读
--4)SERIALIZABLE:串行化
--Oracle只支持1)、4)两种级别,默认为1)级别
10、在JDBC中可以使用Connection的setTransactionIsolation(int level)方法来设置隔离级别。其参数有Connection.TRANSACTION_READ_UNCOMMITTED、Connection.TRANSACTION_READ_COMMITED、Connection.TRANSACTION_REPEATABLE_READ、Connection.TRANSACTION_SERIALIZABLE和Connection.TRANSACTION_NONE五种。