【Java学习】JDBC事务

概述

在开发中,咱们对数据库的多个表或对一个表的多条数据执行更新操做的时候,要保证多个更新操做要么同时成功、要么都不成功。这就涉及到多个更新操做的事务管理问题了。sql

例如:银行的转帐问题,A用户向B用户转帐100元,假设A用户和B用户的钱都存储在Account表中,那么A向B转帐就涉及同时更新Account表中的A用户的钱和B用户的钱,否则的话,A的钱少了,而B却没有收到钱,这是不容许出现的事件。数据库

update account set money = money -100 where name = 'A';
update account set money = money + 100 where name = 'B';

事务

为何上面的sql语句不可以实现“要么都成功、要么都失败”?这是由于若是JDBC处于自动提交模式,每一个SQL语句在完成后都会提交到数据库,也就是说在执行A扣钱(即第一条sql)语句以后,他就已经更新了数据库,若是这个时候程序忽然崩溃,致使后面的语句没有运行,那么就出现了咱们说的,a扣钱了,可是b却没收到钱。并发

因此咱们须要考虑是否关闭自动提交而且管理本身的事务。spa

事务可以控制什么时候更改提交并应用于数据库。它将单个SQL语句或一组SQL语句视为一个逻辑单元,若是任何语句失败,整个事务将失败。.net

如上面所说,JDBC链接默认是处于自动提交,咱们须要手动的打开这个功能。调用Connection对象的setAutoCommit()方法,将false传递给setAutoCommit(),就关闭了自动提交。也能够创第一个布尔值true来打开它。3d

conn.setAutoCommit(false);

如今咱们知道了,想要让多条更新语句保持原子性,首先要关闭自动提交,而后手动提交,在一个事务失败的时候,要进行回滚。code

提交和回滚

完成更改后,若要提交更改,须要在对象上调用commit()方法:orm

conn.commit();

不然要进行回滚对象

conn.rollback();

如下实例说明了如何使用提交和回滚。blog

try{
    conn.setAutoCommit(false);
    Statement stmt = conn.createStatement();
    
    String SQL = "INSERT INTO Employees" + "VALUES (106,20,'Rita,'Tez')";
    stmt.executeUpdate(SQL);
    
    String SQL = "IMSERT IN Employees " + "VALUES (107,22,'SITA','SINGH')";
    stmt.excuteUpdate(SQL);
    
    conn.commit();

}catuch(SQLException se){
    conn.rollback();
    
}

使用保存点

新的JDBC3.0新添加了Savepoint接口提供了额外的事务控制能力。
使用Connection对象两个方法来建立Savepoint对象。

setSavepoint(String savepointName);//定义新的保存点,返回`Savepoint`对象。
releaseSavepoint(Savepoint savepointName);//删除保存点。参数是由上面的方法生出的对象。

这样使用rollback(String savepointName)方法,就能够将事务回滚到指定的保存点

try{
   //Assume a valid connection object conn
   conn.setAutoCommit(false);
   Statement stmt = conn.createStatement();

   //set a Savepoint
   Savepoint savepoint1 = conn.setSavepoint("Savepoint1");
   String SQL = "INSERT INTO Employees " +
                "VALUES (106, 24, 'Curry', 'Stephen')";
   stmt.executeUpdate(SQL);  
   //Submit a malformed SQL statement that breaks
   String SQL = "INSERTED IN Employees " +
                "VALUES (107, 32, 'Kobe', 'Bryant')";
   stmt.executeUpdate(SQL);
   // If there is no error, commit the changes.
   conn.commit();

}catch(SQLException se){
   // If there is any error.
   conn.rollback(savepoint1);
}

事务的隔离性

以上咱们说明了,如何实现一个数据要么都成功,要么都失败,这个实际上是在事务中的原子性。而另外一个比较重要的就是隔离性

什么是隔离性

所谓隔离性是指事务与事务之间的隔离,即在事务提交之间,其余事务中与未完成的事务的数据中间状态访问权限,具体能够经过设置隔离级别来进行控制。

并发事务可能出现的状况

脏读

一个事务读取另外一个事务还没有提交的数据。

clipboard.png

这个解决办法,就是在事务进行操做的时候,禁止该事物进行读操做。

不可从新读

其余事务的操做致使某一个事务两次读取数据不一致。

clipboard.png

幻读

其余事务的数据操做致使某个事务两次读取数据数量不一致。

参考资料

JDBC应用中的事务管理
Mysql数据库事务在jdbc中的用法
JDBC事务和事务的隔离等级

未完待续。。。

相关文章
相关标签/搜索