资讯专栏INFORMATION COLUMN

【Java学习】JDBC事务

weapon / 1469人阅读

摘要:所以我们需要考虑是否关闭自动提交并且管理自己的事务。事务能够控制何时更改提交并应用于数据库。并发事务可能出现的情况脏读一个事务读取另一个事务尚未提交的数据。幻读其他事务的数据操作导致某个事务两次读取数据数量不一致。

概述

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

例如:银行的转账问题,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却没收到钱。

所以我们需要考虑是否关闭自动提交并且管理自己的事务。

事务能够控制何时更改提交并应用于数据库。它将单个SQL语句或一组SQL语句视为一个逻辑单元,如果任何语句失败,整个事务将失败。

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

conn.setAutoCommit(false);

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

提交和回滚

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

conn.commit();

否则要进行回滚

conn.rollback();

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

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);
}
事务的隔离性

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

什么是隔离性

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

并发事务可能出现的情况 脏读

一个事务读取另一个事务尚未提交的数据。

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

不可重新读

其他事务的操作导致某一个事务两次读取数据不一致。

幻读

其他事务的数据操作导致某个事务两次读取数据数量不一致。

参考资料

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

未完待续。。。

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/76364.html

相关文章

  • Spring Boot - 整合JdbcTemplate、MyBatis

    摘要:更简答的说就是要么全部执行成功,要么撤销不执行。因此,数据库操作的事务习惯上就称为事务。实现原理单机事务事务是用对象控制的。接口提供了两种事务模式自动提交和手工提交。事务多机事务,通过实现,需要驱动支持。局限于应用使用。 Spring Boot - 数据库配置 回顾 Spring Boot - 初识 Hello World Spring Boot - Servlet、过滤器、监听器、...

    Keagan 评论0 收藏0
  • Mybatis学习笔记

    摘要:学习笔记有官方的中文开发文档并且针对使用者比较友好是一款优秀的持久层框架,它支持定制化存储过程以及高级映射。它只和配置有关,存在的意义仅在于用来减少类完全限定名的冗余,为了简化中的书写。 Mybatis学习笔记 mybatis有官方的中文开发文档并且针对使用者比较友好:http://www.mybatis.org/mybatis-3/zh/ MyBatis 是一款优秀的持久层框架,它支...

    jsyzchen 评论0 收藏0
  • Java学习JDBC学习(了解CLass等)

    摘要:同时也有一些儿高级的处理,比如批处理更新事务隔离和可滚动结果集等。连接对象表示通信上下文,即,与数据库中的所有的通信是通过此唯一的连接对象。因为是针对类的关系而言,所以一个对象对应多个类的实例化。返回表示查询返回表示其它操作。 JDBC是什么? JDBC是一个Java API,用中文可以通俗的解释为,使用Java语言访问访问数据库的一套接口集合。这是调用者(程序员)和实行者(数据库厂商...

    cjie 评论0 收藏0
  • jdbc就是这么简单

    摘要:使用执行单元测试查询获取连接对象根据连接对象,得到执行语句,返回遍历结果集查询获取连接对象根据连接对象,得到执行添加影响的行数,,如果大于表明操作成功。否则失败更新成功更新失败光标选中方法名字,然后右键执行单元测试。 文章有不当之处,欢迎指正,如果喜欢微信阅读,你也可以关注我的微信公众号:好好学java,获取优质学习资源。 一、JDBC JAVA Database Connectivi...

    li21 评论0 收藏0

发表评论

0条评论

weapon

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<